java注解
annotation并不直接影响代码,不会改变程序的变异方式,java编译器对于包含注解和不包含注解的代码会生成相同的虚拟机指令
注解使用范围
注解使用方法
基本定义
1 2
| public @interface MyAnnotation{ }
|
此时的注解MyAnnotation可使用在任何地方(此时没有限定使用范围 )
1 2 3
| @MyAnnotation public void test(){ }
|
1 2 3
| public @interface MyAnnotation{ String value(); }
|
此时的注解MyAnnotation带有参数,注解是需要带上参数
1 2 3
| @MyAnnotation(value="VALUE") public void test(){ }
|
如果将通过default 指定默认值,则在使用注解时,可省去value的值,此时使用默认值”DEFAULT”,如下:
1 2 3
| public @interface MyAnnotation{ String value() default "DEFAULT"; }
|
1 2 3
| @MyAnnotation public void test(){ }
|
元注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 注解的注解,用来注解所定义的注解 @Target 枚举ElementType有ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE。 TYPE: 适用于class,interface,enum FIELD: 适用于field METHOD: 适用于methond PARAMETER: 适用于methond上的parameter CONSTRUCTOR: 适用于constructor LOCAL_VARIABLE: 适用于局部变量 ANNOTATION_TYPE: 适用于annotation PACKAGE: 适用于package @Retention 枚举RetentionPolicy有CLASS,RUNTIME,SOURCE三种枚举值。 CLASS: 注解会被编译器保留在class文件中,但不会被VM读取。 RUNTIME: 注解会被编译器保留在class文件中,会被VM在运行时获取,因此能被反射机制读取。 SOURCE: 注解会被编译器丢弃。 默认值为CLASS。
|
1 2 3 4 5
| @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation{ String value(); }
|
1 2 3 4
| @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation{ String say(); }
|
当为RetentionPolicy.RUNTIME,那么问题来了,我们可以通过反射机制,在运行时来获取注解信息
1 2 3 4 5 6 7 8 9
| public class TestAnnotation{ public TestAnnotation(){ AnnotationHelper.register(this); } @MyAnnotation(say="TEST") public void test(){ System.out.println("TestAnnotation test()"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class AnnotationHelper { public static void register(Object obj){ Class<?> clz=obj.getClass(); for(Method m:clz.getDeclaredMethods()){ MyAnnotation ma=m.getAnnotation(MyAnnotation.class); if(ma!=null){ System.out.println(ma.say()); } }
} }
|
1 2 3 4 5
| public class MainTest{ public static void main(String[] agrs){ new TestAnnotation().test(); } }
|
输出结果为:TEST