Java 注解

来源:互联网 发布:西南交大希望学院网络 编辑:程序博客网 时间:2024/05/21 13:57

Java 基本注解

JDK中的三个基本的注解:
1. @Override:检查子类确实是覆盖了父类的方法。
2. @Deprecated:说明已经过时了。
3. @SuppressWarnings({ “unused”, “deprecation” }):抑制程序中的警告。unused警告的类型。{}数组。all抑制所有警告。

public class 基本注解 {    @SuppressWarnings("all")// 不提示警告    public void ff(){        int i = 0;        System.out.println("abc");        List list = new ArrayList();        System.out.println(new Date().toLocaleString());    }    // 供子类重写    public void l1l1lll1l1l1l1(){}}class 基本注解2 extends 基本注解{    public void ff(){    }    @Deprecated// 过时    @Override// 重写,检测。检测方法名是否写错    public void l1l1lll1l1l1l1(){        System.out.println(new Date().toLocaleString());    }}

自定义注解

自定义注解的语法(肉体):

        声明一个注解   @interface  注解名 {}        public @interface MyAnnotation {}        注解的 本质 就是一个接口,这个接口需要继承 Annotation接口。        public interface MyAnnotation extends java.lang.annotation.Annotation {}
  1. 注解的属性和方法
    注解本质上就是接口,接口中可以有属性和方法
    属性 : 例:int age();
  2. 关于注解的属性类型可以有哪些?
    1. 基本类型
    2. String
    3. 枚举类型
    4. 注解类型
    5. Class类型
    6. 以上类型的一维数组类型
  3. 自定义一个注解

    public @interface MyAnnotation {    int age() default 0;    String name() default "";    String sex() default "";    // String value();    String[] value();    // MyAnno anno();    // Color color();}// 枚举public enum Color {    red,blue,green}
  4. 注解的使用

    public class 自定义注解 {//  @MyAnnotation(age=18,name="tom",sex="男",value="aa")    @MyAnnotation({"aaa","bbb"})    public void ff(){    }}

注解的反射(灵魂):

1.元注解

SOURCE;
CLASS;
RUNTIME;
状态图解
状态图解

1. 什么是元注解:        只能用在注解上的注解叫做元注解。(即:用于修饰注解的注解)2. 注释类型      @Retention:作用。改变自定义的注解的存活范围。        RetentionPolicy:            注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。            1. SOURCE:                 编译器要丢弃的注释。            2. CLASS:                编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。            3. RUNTIME:                编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。    @Target:作用,指定该注解能用在什么地方。        ElementType:            程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。            1. ANNOTATION_TYPE                 注释类型声明            2. CONSTRUCTOR                 构造方法声明            3. FIELD                 字段声明(包括枚举常量)            4. LOCAL_VARIABLE                 局部变量声明            5. METHOD                 方法声明            6. PACKAGE                 包声明            7. PARAMETER                 参数声明            8. TYPE                 类、接口(包括注释类型)或枚举声明    @Documented:        作用,使用了@MyTest的注解的类,如果@MyTest注解上面有@Documented注解,那么使用了@MyTest的注解的类的API文档中会出现@MyTest的身影。    @Inherited:        作用,说明该注解可以被继承下去。    

定义一个由元注解修饰的自定义注解

@Documented@Inherited@Retention(RetentionPolicy.RUNTIME)@Target({ ElementType.METHOD, ElementType.TYPE })public @interface MyTest {    long timeout() default -1; //}

定义一个测试类,由元注解修饰

@MyTestpublic class SomeDaoImpl {    @MyTest(timeout=1000000)    public void testAdd(){        System.out.println("add方法执行了");    }    @MyTest    public void testUpdate(){        System.out.println("update方法执行了");    }}

2.注解实现

java.lang.reflect.AnnotatedElement:    1. <T extends Annotation> T getAnnotation(Class<T> annotationType):        得到指定类型的注解引用。没有返回null。    2. Annotation[] getAnnotations():        得到所有的注解,包含从父类继承下来的。    3. Annotation[] getDeclaredAnnotations():        得到直接存在于此元素上的所有注解。    4. boolean isAnnotationPresent(Class<? extends Annotation> annotationType):        判断指定的注解有没有。ClassMethodFieldConstructor等实现了AnnotatedElement接口.如:    Class.isAnnotationPresent(MyTest.class):        判断 类 上面有没有@MyTest注解;    Method.isAnnotationPresent(MyTest.class):        判断 方法 上面有没有@MyTest注解。

查看 测试类 中的方法,哪 个有@MyTest就执行哪个方法

private static void test1() throws IllegalAccessException,            InvocationTargetException, InstantiationException {        //得到要执行的类的Class对象        Class clazz = SomeDaoImpl.class;        //得到类中的方法,包括本类中和父类中的所有公共的方法        Method[] methods = clazz.getMethods();        //遍历所有方法        for (Method m : methods) {            //判断当前方法上是否有@MyTest注解            boolean isExistsAnno = m.isAnnotationPresent(MyTest.class);//          System.out.println(m.getName()+"当前方法是否有注解:"+isExistsAnno);            if(m.isAnnotationPresent(MyTest.class)){                m.invoke(clazz.newInstance(), null);            }        }    }

调用注解方法

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {        Class clazz = SomeDaoImpl.class;        Method[] methods = clazz.getMethods();        for (Method m : methods) {            //得到当前方法上的注解对象            MyTest myTest = m.getAnnotation(MyTest.class);            if(myTest!=null){//如果当前方法上有@MyTest注解                long timeout = myTest.timeout();                if(timeout<0){//表示不需要测试,默认 -1                    m.invoke(clazz.newInstance(), null);                }else{//需要测试                    long l1 = System.nanoTime();//得到执行前纳秒                    m.invoke(clazz.newInstance(), null);                    long l2 = System.nanoTime();//得到执行后纳秒                    if((l2-l1)>timeout){                        System.out.println(m.getName()+"方法超时!");                    }                }            }        }}