自定义注解

Description.java(这里自定义Description注解)


package com.ann.test;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//元注解:修饰注解的注解
/*
* @Target 注解--》声明自定义注解的作用域
* CONSTRUCTOR 构造方法声明
* FIELD 字段声明
* LOCAL_VARIABLE 局部变量声明
* METHOD 方法声明
* PACKAGE 包声明
* PARAMETER 参数声明
* TYPE 类,接口
*/
/*
* @Retention 注解--》声明自定义注解的生命周期
* SOURCE 只在源码显示,编译时会被丢弃
* CLASS 编译时会记录到class中,运行时忽略
* RUNTIME 运行时存在,可以通过反射读取
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited //允许子类继承 -> 而且子类只会继承 作用在类作用域的注解
@Documented //生成javadoc时会包含注解

//自定义注解
/*
* 使用 @interface 关键字定义注解
* 成员以无参无异常方式声明
* 可以用default为成员指定一个默认值
* 成员类型是受限的,合法类型包括原始类型及String, Class, Annotation, Enumeration
* 如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)
* 注解类可以没有成员,没有成员的注解为标识注解
*/
public @interface Description {
/*String desc();

String author();

int age() default 18;*/

String value();
}

       注解的使用:

Person.java (Person类使用Description注解)


package com.ann.test;

//该注解可以被子类继承
@Description("I am class annotation")
public class Person {

//该注解将不会被子类继承
@Description("I am method annotation")
public String name() {
return null;
}

public int age() {
return 0;
}

@Deprecated
public void sing() {

}
}


       注解的继承:

Child.java (类上会继承Description注解(即 @Description("I am class annotation") ),而方法则不会)


package com.ann.test;

public class Child extends Person {

@Override
public String name() {
// TODO Auto-generated method stub
return null;
}

@Override
public int age() {
// TODO Auto-generated method stub
return 0;
}

@Override
public void sing() {
// TODO Auto-generated method stub

}

}


       解析注解:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

ParseAnn.java


package com.ann.test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

//解析注解(只能获取到运行时注解)
public class ParseAnn {
public static void main(String[] args) {

try {
//1.使用类加载器加载类
Class c = Class.forName("com.ann.test.Child");
//2.找到类上面的注解
boolean isExist = c.isAnnotationPresent(Description.class);
if(isExist) {
//3.拿到注解实例
Description d = (Description) c.getAnnotation(Description.class);
System.out.println(d.value());
}

//4.找到方法上的注解
Method[] ms = c.getMethods();
for(Method m : ms) {
boolean isMExist = m.isAnnotationPresent(Description.class);
if(isMExist) {
Description d = (Description)m.getAnnotation(Description.class);
System.out.println(d.value());
}
}

//另外一种解析方法
for(Method m : ms) {
Annotation[] as = m.getAnnotations();
for(Annotation a : as) {
if(a instanceof Description) {
Description d = (Description)a;
System.out.println(d.value());
}
}
}

} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
}

       运行结果如下:

Java中的自定义注解_注解


        Child.java 只继承了父类的类作用域上的注解。只输出了类上的注解。