Java基础回顾 —注解
-
常见一些注解:
@Override 表示子类要重写父类的对应方法。
@Deprecated 表示方法是不建议被使用的( RetentionType是Runtime的)。
@SuppressWarnngs 注解表示遗址警告。 -
自定义注解:
当注解的属性名为value时,在对其赋值时可以不指定属性名称而直接写上属性值即可;
除了value以外的其他值都需要使用name=value这种赋值方式,即明确制定给谁赋值。 -
当我们使用@interface关键字定义一个注解时,该注解隐含地实现了java.lang.annotation.Annotation接口; 如果我们定义了一个接口,并且让这个接口继承自Annotation,那么我们所定义的接口依然还是接口而不是注解;Annotation本身是接口而不是注解。
-
补充:
注解是用来代替XML的另一种 元数据metadata。
注解只支持基本类型,String类型及枚举类型。
反射中Method类提供一个 isAnnotationPresent(Class<?>)类,用来check这个方法是否持有那个注解。 -
定义注解所需要的注解:
- @Documented –注解是否将包含在JavaDoc中
- @Retention –什么时候使用该注解
- @Target –注解用于什么地方
- @Inherited – 是否允许子类继承该注解
-
@Target:
@Target – 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性,那么你需要在定义target包含所有的属性。 -
@Retention:
- RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
tips: 注解类型信息只会保留在Java源文件中,而不会保存在编译好的class文件中。 - RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
tips: 注解类型信息会保留在Java和class文件中,但是在使用该类时,这些注解信息不会加载到JVM中。 - RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
tips: 这些注解类型会存在于Java和class文件,同时也会加载到JVM中。
- RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
-
example 注解和反射结合使用:
MyClass myClass = new MyClass(); Class<?> clazz = MyClass.class; Method method = clazz.getMethod("test",new Class[]{}); //Check whether the annotation type is exist for this method or not. if(method.isAnnotationPresent(MyAnnotation.class)){ //this only work when the retention type is runtime. method.invoke(myClass, new Object[]{}); } //Get the annotation type MyAnnotationmyAnnotation = method.getAnnotation(MyAnnotation.class); System.out.println(myAnnotation.name());; } //Get all annotations for this method Annotation[] anns = method.getAnnotations(); for(Annotation ann : anns){ System.out.println(ann.annotationType().getName()); }
典型事例:Junit框架主要还是依靠 反射机制。
Junit4 通过注解的执行一般流程:
- 首先获得带测试类所对应的Class对象。
- 然后通过该Class对象获得当前类中所有的public方法所对应的Method数组。
- 遍历改Method数组,获取每一个Method对象。
- 调用每一个Method对象的isAnnotationPresent ( Test.class )方法,判断该方法是不是被@Test注解所修饰。
- 如果改方法返回true,那么调用method.invoke()方法去执行该方法,否则不执行。