Java 注解

77 阅读2分钟

概述

    Annotation注解,是一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。

    对比注释:注释是给开发人员阅读的,注解是给计算机提供相应信息的。

    注解的作用:

  1. 编译检查:通过代码里标识注解,让编译器能够实现基本的编译检查。例如:@Override
  2. 代码分析:通过代码里标识注解,对代码进行分析,从而达到取代xml目的。
  3. 编写文档:通过代码里标识注解,辅助生成帮助文档对应的内容

常见注解:
@Deprecated 过时,过时的方法不建议使用,但仍可以使用。
@Override JDK5.0表示复写父类的方法;JDK6.0 还可以表示实现接口的方法
@SuppressWarnings 表示抑制警告,被修饰的类或方法如果存在编译警告,将被编译器忽略
deprecation 忽略过时
rawtypes 安全警告
unused 未使用警告
null 忽略空指针
all 忽略所有警告

自定义注解:

修饰符 @interface MyAnno2{
    //修饰符 返回值 名称() [default "xx"]
    public String[] getName() ;
    public String getAge();
	public String username() default "jack";
}
自定义的注解必须要加上元注解才能使用(重点)

//必选元注解
//1.@Retention() 指定当前注解的生命周期
//RetentionPolicy.SOURCE 存在于源码中
//RetentionPolicy.CLASS 存在于源码和字节码中 运行的时候内存中没有
//RetentionPolicy.RUNTIME 所有地方都有

//2.@Target() 指定注解使用的位置
//ElementType.TYPE 修饰类 接口 枚举
//ElementType.FIELD 修饰属性
//ElementType.METHOD 修饰方法
//ElementType.CONSTRUCTOR 修饰构造器

//可选元注解
//3.Documented 用于生成doc文档
//4.Inherited 用于修饰 父类的注解子类是否继承

获取与使用

public void test3() throws NoSuchFieldException {
    Class u = User.class;
    Field uid = u.getDeclaredField("uid");
    uid.setAccessible(true);
    //判断是否有注解isAnnotationPresent(Class c)
    System.out.println(uid.isAnnotationPresent(MyAnn.class));
    //获取所有注解
    Annotation[] arr = uid.getAnnotations();
    for(Annotation an:arr){
        System.out.println(an);
    }
    //获取单个指定的注解
    MyAnn m = uid.getAnnotation(MyAnn.class);
    System.out.println(Arrays.toString(m.getName()));
    System.out.println(m.getAge());
}
public class User {
    private String userName;
    private String sex;
    @TimeType(type = DateFormatType.ALL)
    private Date birth;

	public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
	public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    //获取当前的出生年月
    public String getBirth()  {
        Class c = this.getClass();
        Field f = null;
        try {
            f = c.getDeclaredField("birth");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        String s = "";
        if(birth!=null){
            s = birth.toString();
            //判断这个属性上是否有 timetype注解
            if(f.isAnnotationPresent(TimeType.class)){
                TimeType timeType = f.getAnnotation(TimeType.class);
                DateFormatType i = timeType.type();
                if(i == DateFormatType.SIMPLE) {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    s = sf.format(birth);
                }else if(i==DateFormatType.SIMPLE2){
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
                    s = sf.format(birth);
                }else if(i == DateFormatType.ALL){
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    s = sf.format(birth);
                }
            }
        }
        return s;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }
    
    @Override
    public String toString() {
        return "User{" +
                "uid='" + uid + '\'' +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                '}';
    }    
}