pppploi8's Blog

欢迎来到pppploi8的个人博客!

Java学习笔记-注解

注解毫无疑问是一个很好玩的特性,之前看书的时候也没有太过注意,最近看Spring实战的时候又看到了自定义注解,于是忍不住把Java编程思想掏出来重新看了下注解这章,顺带记个笔记

注解的形式就是代码里写的比如

@Override

这样的代码

和注释相比较,最主要的也是最有趣的地方在于注解可以自定义,而且也可以使用反射来调用被注解的类,方法

在Java里创建自定义注解的格式如下

/*
 * file:Test.java
 */
package javaapplication;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
    public int id();
    public String text() default "Null";
}

于是我们就可以在代码里使用注解了,比如这样

/*
 * file:JavaApplication.java
 */
package javaapplication;
import java.lang.reflect.Method;
class TestObject {
    @Test(id = 233,text = "Hello")
    public void testA(int id,String text){
        System.out.println("id:"+id+"\ttext:"+text);
    }
    @Test(id = 10)
    public void testB(int id,String text){
        System.out.println("id:"+id+"\ttext:"+text);
    }
}
public class JavaApplication {
    public static void main(String[] args) throws Exception{
        TestObject to = new TestObject();
        //通过反射来使用注解里的数据动态调用方法
        for (Method m : TestObject.class.getDeclaredMethods()) {
            Test t = m.getAnnotation(Test.class);
            if (t != null) {
                m.invoke(to, t.id(),t.text());
            }
        }
    }
}

简单说了说注解的写法,然后来谈谈元注解

元注解就是用来注解注解的注解,恩,我故意说这么绕的

就是@Target之类的,具体Java编程思想上给出下表

@Target 表示该注解可以用于什么地方。可能的ElementType参数包括:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
@Retention 表示需要在什么级别保存注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
@Documented 将此注解包含在Javadoc中
@Inherited 允许子类继承父类中的注解

另外,注解元素支持以下类型

  • 所有基本类型(int,float,boolean等)
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组

注解简单的笔记就到这里结束了

注解还可以用apt处理,用于观察者模式,用于单元测试等等,更加详细的说明欢迎阅读《Java编程思想》第20章-注解