1 Annotation提供了一种为程序元素设置元数据方法,就像修饰符一样修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息存储在Annotation的“name=value”对中
2 4个基本annotation
1 限定重写父类方法 @Override
class A { void info() { } } class B extends A { @Override public void info() { } }
2 程序元素已过时 @Deprecated
class A { @Deprecated void info() { } } class B { public void inf() { new A().info(); } }
3 抑制编译器警告
@SuppressWarnings(value="unchecked") public class JDBCTest{ public static void main(String[] args) { List<Object> l = new ArrayList<>(); } }
4 堆污染:把不带泛型对象赋给代泛型变量
public class JDBCTest{ @SafeVarargs public void a() { List l = new ArrayList<Integer>(); List<String> la = l; System.out.println(la.get(0)); } }
3 4 个元Annotation
@Retention 定义注释保留的时间
@Target 定义注释修饰成员单元的类型
@Documented Annotationn 能被提取成文档
@Inherited Annotation 具有继承性
public class JDBCTest extends A{ public static void main(String[] args) { System.out.println(JDBCTest.class.isAnnotationPresent(in.class)); } } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited @interface in{ } @in class A{ }
4 定义Annotation
@Test(age=9) public class JDBCTest{ public static void main(String[] args) { } } @interface Test{ String name() default "dddds"; int age(); }
5 AnnotatedElement 接口是所有程序元素(class method等)的父接口。
AnnotatedElement a = JDBCTest.class;
a.getAnnotation(Test.class);
a.isAnnotationPresent(Test.class);
a.getDeclaredAnnotations();
public class JDBCTest{ @Test(age=9) public void info(){} public static void main(String[] args) throws Exception, SecurityException { JDBCTest t = new JDBCTest(); Test b = t.getClass().getMethod("info").getAnnotation(Test.class); System.out.println(b.age()); System.out.println(b.name()); } } @Retention(RetentionPolicy.RUNTIME) @interface Test{ String name() default "dddds"; int age(); }
class My { @Testable public void m1() { } public void m2() { } @Testable public void m3() { throw new RuntimeException("dfds"); } } public class JDBCTest{ public static void main(String[] args) throws Exception { int pass = 0; int field = 0; for (Method m : Class.forName("com.whe.db.My").getMethods()){ if (m.isAnnotationPresent(Testable.class)) { try { m.invoke(null); pass++; } catch (Exception e) { // TODO: handle exception field++; } } } System.out.println("pass = " + pass + " field = " + field); } } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface Testable{ }