1 自定义注解
1.1 介绍
1.2 API说明
- ElementType:作用域,在下面类型的地方起作用,其他地方无效
- TYPE:允许被修饰的注解作用在类、接口和枚举上
- FIELD:允许作用在属性字段上
- METHOD:允许作用在方法上
- PARAMETER:允许作用在方法参数上
- CONSTRUCTOR:允许作用在构造器上
- LOCAL_VARIABLE:允许作用在本地局部变量上
- ANNOTATION_TYPE:允许作用在注解上
- PACKAGE:允许作用在包上
- RetentionPolicy:注解的生命周期
- SOURCE:当前注解编译期可见,不会写入 class 文件
- CLASS:类加载阶段丢弃,会写入 class 文件
- RUNTIME:永久保存,可以反射获取
- @Target:修饰对象范围
- 格式:@Target({ElementType.TYPE,ElementType,METHOD})
- @Retention:保留时间
- 格式:@Retention(RetentionPolicy.SOURCE)
- @Inherited:允许子类继承
-
1.3 使用
自定义注解格式:
public @interface 注解名{
// 定义体
}
获取注解信息
获取当前类上的注解
Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");
MayiktName declaredAnnotation = aClass.getDeclaredAnnotation(MayiktName.class);
System.out.println(declaredAnnotation);
获取当前方法上的注解
Method userNameMethod = aClass.getDeclaredMethod("getUserName");
MayiktName declaredAnnotation = userNameMethod.getDeclaredAnnotation(MayiktName.class);
System.out.println(declaredAnnotation);
获取字段上的注解
Field pubUserName = aClass.getDeclaredField("pubUserName");
final MayiktName declaredAnnotation = pubUserName.getDeclaredAnnotation(MayiktName.class);
System.out.println(declaredAnnotation);
获得构造方法注解
// 先获得构造方法对象
Constructor<TestAnnotation> constructors = aClass.getConstructor(new Class[] {});
MyConstructorAnnotation myConstructorAnnotation = constructors.getAnnotation(MyConstructorAnnotation.class);// 拿到构造方法上面的注解实例
System.out.println(myConstructorAnnotation.desc() + "+" + myConstructorAnnotation.uri());
1.4 常用案例
1.4.1 获取字段描述与字段长度
自定义注解
@Target(ElementType.FIELD) // 注解用于字段上
@Retention(RetentionPolicy.RUNTIME) // 保留到运行时,可通过注解获取
public @interface MyFeild{
/**
* 描述字段作用
*/
String description();
/**
* 字段长度
*/
int length();
}
实现注解和测试注解
public class AnnoTest {
// 使用我们的自定义注解
@MyField(description = "用户名", length = 12)
private String username;
@Test
public void testMyField(){
// 获取类模板
Class c = AnnoTest.class;
// 获取所有字段
for(Field f : c.getDeclaredFields()){
// 判断这个字段是否有MyField注解
if(f.isAnnotationPresent(MyField.class)){
// 拿到注解实例
MyField annotation = f.getAnnotation(MyField.class);
System.out.println("字段:[" + f.getName() + "], 描述:[" + annotation.description() + "], 长度:[" + annotation.length() +"]");
}
}
}
}
结果
1.4.2 获取类的描述和方法的描述
自定义注解
// 注解的作用域
@Target({ElementType.METHOD, ElementType.TYPE})
// 注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
// 允许子类继承
@Inherited
// 生成javadoc的时候生成注解的信息
@Documented
// @interface:使用@interface关键定义注解
public @interface Description {
// 注解的成员
// 成员类型所限的,合法的类型包括原始数据类型及String、Class、Annotation、Enumeration
String desc();
String author();
// 成员以无参无异常方式生命,可以用default为成员指定一个默认值
int age() default 18;
// 如果注解成员只有一个时,成员名必须取名未value(),在使用时可以忽略成员名和赋值号(=)
// 注解可以没有成员,没有成员的注解成为标识注解
}
调用注解 ```java @Description(desc=”I am class annotation”, author=”hd”) public class TestDescription {
@Description(desc=”I am method annotation”, author=”hd”) public String test(){
return "red";
}
}
- 实现注解
```java
/**
* 解析注解
* 通过反射获取类,函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑
*
* 对于一个类或者接口来说,Class 类中提供了以下一些方法用于反射注解。
getAnnotation:返回指定的注解
isAnnotationPresent:判定当前元素是否被指定注解修饰
getAnnotations:返回所有的注解
getDeclaredAnnotation:返回本元素的指定注解
getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的
*
* @author H__D
* @date 2019-07-09 22:52:42
*
*/
public class ParseDecription {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 1、使用类加载器加载类
try {
Class c = Class.forName("com.xkcoding.test.TestDescription");
System.out.println(c);
// 2、找到类上面的注解
boolean isExist = c.isAnnotationPresent(Description.class);
if(isExist) {
// 3、拿到注解实例
Description d = (Description) c.getAnnotation(Description.class);
System.out.println("========parse class annotation=========");
System.out.println("desc = " + d.desc());
System.out.println("author = " + d.author());
System.out.println("age = " + d.age());
}
// 4、找到方法上的注解
Method[] ms = c.getMethods();
for (Method m : ms) {
boolean isMExist = m.isAnnotationPresent(Description.class);
if(isMExist) {
Description d = m.getAnnotation(Description.class);
System.out.println("========parse method annotation=========");
System.out.println("desc = " + d.desc());
System.out.println("author = " + d.author());
System.out.println("age = " + d.age());
}
}
// 另外一种解析方法
for (Method m : ms) {
Annotation[] annotations = m.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof Description) {
System.out.println("========parse method annotation other way=========");
Description d = (Description) annotation;
System.out.println("desc = " + d.desc());
System.out.println("author = " + d.author());
System.out.println("age = " + d.age());
}
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 结果
2 常用注解
- @Override:表示方法重写。
- @Deprecated:表示过时的方法。
- @SuppressWarnings:表示忽略警告。