Annotation
不但可以包含功能性的实际代码,也添加了对元数据的支持,这些标记可以在编译、加载、运行时被读取执行。例如在某些框架中,增加注解,简化配置
常用注解
@Override: 表示继承父类中方法
@Deprecated:表示该方法不被建议使用
@SuppressWarings :表示抑制告警
元注解(可以修饰注解类的注解)
@Target:表示注解运用的场景;
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Retention:表示注解的存活时间
- RetentionPolicy.SOURCE 注解将被编译器丢弃,存在源码期间
- RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
- RetentionPolicy.RUNTIME JVM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
@Document:表示将注解中的元素包含到javadoc中
@Inherited:表示子类可继承父类中的注解
@Repeatable:表示标记的注解可以多次应用于相同的声明或类型(注解的值可取多个)
=====================================================
自定义注解
1.定义注解
2.使用注解
/** 自定义注解 自定义注解可以被注解修饰,Retention注解中的值为runtime时,表示为运行时注解 Target注解中值为method时,表示该注解修饰方法 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnatation { String hello() default "shanghai"; String world(); }
@Deprecated public class Mytest { @MyAnnatation(world = "abc") @Deprecated @SuppressWarnings("unchecked") public void output() { System.out.println("out put something"); } }
public class TestReFlection { public static void main(String[] args) throws Exception{ Mytest mytest = new Mytest(); Class<Mytest> clazz = Mytest.class; Method method = clazz.getMethod("output", new Class[]{}); //如果注释被RetentionPolicy.RUNTIME修改,则返回true if (method.isAnnotationPresent(MyAnnatation.class)) { method.invoke(mytest, new Object[]{}); MyAnnatation myAnnatation = method.getAnnotation(MyAnnatation.class); String hello = myAnnatation.hello(); String world = myAnnatation.world(); System.out.println(hello + " " + world); } //.getAnnotations()只会返回运行时注解 for (Annotation annotations : method.getAnnotations()) { System.out.println(annotations.annotationType().getName()); } } }
实际案例
Junit
/** * 含有Test注解的就是需要测试的方法,方法名称不需要必须以test开头 * */ public class JunitTest1 { @Test public void junitTest() { System.out.println("haha"); } }
public class JunitTest extends TestCase { public void testUnit() { System.out.println("haha"); } }
Junit执行过程
首先获得带测试类所对应的class对象
然后通过该class对象获得当前类中所有public方法所对应的method数组
便利该method数组,获得每一个method对戏那个
调用每个method对象的isAnnatationPresent()方法,判断该方法是否被Test注解所修饰
如果该方法返回true,那么调用method.invoke()方法执行该方法,都则不执行
单元测试不是为了证明你是对的,而是证明你没有错误