Java注解
- 概念
- 元注解
- 注解的分类
- 解析注解
- 自定义注解
- 注解的项目实战
- 注解总结
概念
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
-
jdk自带注解:
@Override(覆盖或重写父类的方法)
@SuppressWarnings(表示忽略指定警告)等
-
第三方注解 如spring注解
元注解
元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种
@Target
表示注解运用在什么地方
- ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
- ElementType.CONSTRUCTOR 可以给构造方法进行注解
- ElementType.FIELD 可以给属性进行注解
- ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
- ElementType.METHOD 可以给方法进行注解
- ElementType.PACKAGE 可以给一个包进行注解
- ElementType.PARAMETER 可以给一个方法内的参数进行注解
- ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Retention
注解存活时间
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,不会被加载到JVM中
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,被加载进入到JVM中,所以在程序运行时可以获取到
@Documented
将注解中的元素包含到Javadoc中去
@Inherited
一个超类被 @Inherited 注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}
//Test 被 @Inherited 修饰,之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解
注解的分类
按运行机制
- 源码注解(只在源码存在)
- 编译注解(在class文件中也存在)
- 运行时注解(在运行阶段仍然起作用)
按照来源
- JDK自带的注解
- 第三方的注解
- 自定义注解
解析注解
借助java.lang.reflect包下AnnotatedElement接口
方法名 | 参数 | 返回值 | 作用 |
---|---|---|---|
isAnnotationPresent | 注解对应的Class | boolean | 检测是否被对应注解修饰 |
getAnnotation | 注解对应的Class | Annotation | 获取注解对象 |
getAnnotations | 无 | Annotation[] | 返回所有注解 |
getDeclaredAnnotations | 无 | Annotation[] | 返回所有注解,忽略继承的注解 |
自定义注解
语法要求
- 使用@interface关键字定义注解
- 成员以无参无异常方式申明
- 可为成员指定默认值
- 如果只有一个成员,并且取名value,使用时可直接省略value=
- 可以没有成员,称为标识注解
实例
通过注解配置,实现一个通用方法,根据用户需求获取到不同的sql语句的简单实例额,现实开发中,需要根据具体情况实现
import java.lang.annotation.*;
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Table {
String value();
}
import java.lang.annotation.*;
@Inherited
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
String value();
}
@Table("user")
public class UserTest {
@Column(value = "id")
private String id;
@Column(value = "userName")
private String userName;
@Column(value = "age")
private String age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public UserTest(String id, String userName, String age) {
this.id = id;
this.userName = userName;
this.age = age;
}
}
import org.apache.commons.lang3.math.NumberUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void anotationTest(Object obj) {
StringBuilder str = new StringBuilder();
Class c = obj.getClass();
if (c.isAnnotationPresent(Table.class)) {
Table table = (Table) c.getAnnotation(Table.class);
str.append("select * from " + table.value() + " where 1=1");
}
Field[] fields = c.getDeclaredFields();
for (Field f : fields) {
String fieldName = f.getName();
String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);//通过拆分获取方法名
try {
Column column = f.getAnnotation(Column.class);
if (column != null) {
Method method = obj.getClass().getMethod(methodName);//获取方法
String value = (String) method.invoke(obj);//获取对象对应方法属性 的值
if (value != null && !value.equals("")) {
if (!NumberUtils.isNumber(column.value()) && !NumberUtils.isNumber(value)) {
// 判断参数是不是 in 类型参数 1,2,3
if (value.contains(",")) {
str.append(" and " + column.value() + " in (" + value + ") ");
} else {
str.append(" and " + column.value() + " like '%" + value + "%' ");
}
} else {
str.append(" and " + column.value() + "=" + value + " ");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(str.toString());
}
public static void main(String[] args) {
Test.anotationTest(new UserTest("1", "lxl,aaa", "20"));
Test.anotationTest(new UserTest("1", "lxl", "20"));
}
}
运行结果
select * from user where 1=1 and id=1 and userName in (lxl,aaa) and age=20
select * from user where 1=1 and id=1 and userName like '%lxl%' and age=20