Loading

Java学习笔记 -注解

概述

  • 1.注解Annotation是一种引用数据类型。编译之后也是生成class文件

  • 2.自定义注解:
    [修饰符列表] @interface 注解类型名{}

  • 3.注解怎么使用,用在什么地方:
    第一:注解使用的语法格式:@注解类型名
    第二:注解可以出现在类上、属性上、方法上、变量上等,注解还可以出现在注解上

示例程序:

//MyAnnotation 注解类型
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    /**
     * 在注解中可以定义属性,以下是MyAnnotation的name属性
     * 看着像一个方法,实际上是属性
     *
     * 属性的类型可以是:
     * 八种基本数据类型、String、class,它们的数组类型也可以
     */
    String name();

    int age() default 22;  //给属性指定默认值

    //如果属性名是value,且只有一个属性的话,则该属性名可以省略
    String value();
}
public enum Season {
    SPRING,SUMMER,AUTUNDO,WINTER

}

@MyAnnotation(name = "lisi", age = 12, value = "ee",season = {Season.SPRING,Season.SUMMER})
public class AnnotationTest01{

    //如果数组中只有一个元素,则大括号可以省略
    @MyAnnotation(name = "zhangsan",value = "ee",season = Season.SPRING)
    public void doSome(){

    }
}

元注解

  • Target:
    用来标注”被标注的注解“可以出现在那些位置上
    @Target(ElementType.METHOD) : 表示”被标注的注解“只能出现在方法上

  • Retention:
    用来”被标注的注解“最终保存在哪里
    @Retention(RetentionPolicy.SOURCE) :表示该注解被保存在java源文件中
    @Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中
    @Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制读取

在此基础上看看 @Override 的源码

@Target(ElementType.METHOD)    //只能出现在方法上
@Retention(RetentionPolicy.SOURCE)  //表示该注解被保存在源文件中
public @interface Override {}
  • 是给编译器参考的,和运行阶段没有关系
  • 如果给方法加上了它,编译器会自动检测是否正确的重写了父类的方法

@Deprecated

@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {}
  • 表示被标注的已过时,不推荐使用
public class AnnotationTest03 {
    public static void main(String[] args) {
        T.doSome(); //doSome有横线
    }
}

class T{
    @Deprecated
    public static void doSome(){

    }
}

通过反射机制获取注解

  • 该注解必须被保存在class文件中,并且可以被反射机制读取

示例程序:

public class RefledtAnnotationTest {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("T");

        //如果c类有MyAnnotation这个注解,则返回true
        if(c.isAnnotationPresent(MyAnnotation.class)){
            MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);

            //专门用来获取属性名为"value"的值
            String value = myAnnotation.value();
            System.out.println(value);
        } else {
            System.out.println(false);
        }

        //获取方法上完整属性
        Method doSomeMethod = c.getDeclaredMethod("doSome");

        if(doSomeMethod.isAnnotationPresent(MyAnnotation.class)){
            MyAnnotation myAnnotation = doSomeMethod.getAnnotation(MyAnnotation.class);
            System.out.println(myAnnotation.name());
            System.out.println(myAnnotation.age());
            System.out.println(myAnnotation.value());
        }
    }
}

注解的使用实例

编写一个注解Id,用来修饰类,如果该类没有定义int id属性,就抛出异常

代码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
public class HasNotIdPropertyException extends RuntimeException{
    public HasNotIdPropertyException(){

    }

    public HasNotIdPropertyException(String s){
        super(s);
    }

}
@Id
public class User {
    int id;
    String name;
    int age;
}
public class Test {
    public static void main(String[] args) throws Exception {
        Class userClass = Class.forName("example.User");

        if(userClass.isAnnotationPresent(Id.class)){

            //获取类的属性
            Field[] fields = userClass.getDeclaredFields();
            boolean flag = false;
            for(Field f : fields){
                if("id".equals(f.getName()) && "int".equals(f.getType().getSimpleName())){
                    flag = true;
                    break;
                }
            }

            if(!flag){
                throw new HasNotIdPropertyException("没有定义int id属性");
            }
        }
    }
}
posted @ 2020-06-05 17:44  Krocz  阅读(173)  评论(0编辑  收藏  举报