平常看到注解,比如@Override之类的,没当回事。最近又看了看spring之类的框架,发现有很多东西都是靠注解驱动的,这就使我有了点好奇。这篇博客写的还行
如果还是一点都不了解的,建议先看推荐的这篇博客。
提示:
元标签有 @Retention、@Documented、@Target、@Inherited、@Repeatable 5 种。
@Retention
Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
它的取值如下:
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,
- 它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
@Documented
顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。
@Target
Target 是目标的意思,@Target 指定了注解运用的地方。
你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。
类比到标签,原本标签是你想张贴到哪个地方就到哪个地方,但是因为 @Target 的存在,
它张贴的地方就非常具体了,比如只能张贴到方法上、类上、方法参数上等等。@Target 有下面的取值
ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
ElementType.CONSTRUCTOR 可以给构造方法进行注解
ElementType.FIELD 可以给属性进行注解
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
ElementType.METHOD 可以给方法进行注解
ElementType.PACKAGE 可以给一个包进行注解
ElementType.PARAMETER 可以给一个方法内的参数进行注解
ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
@Inherited
Inherited 是继承的意思,但是它并不是说注解本身可以继承,
而是说如果一个超类被 @Inherited 注解过的注解进行注解的话,
那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。
@Repeatable
Repeatable 自然是可重复的意思。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。
场景:利用注解自动生成sql语句
相关:
- 表名:t_user
- 主键:t_id
- 姓名:t_userName
- 号码:t_number
开始写代码
开始定义表的注解
该注解声明了智能作用在类上面
注解可以保留到程序运行的时候
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}
开始定义字段的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
实体类
@Table("t_user")
public class Filter {
@Column("t_id")
private int id ;
@Column("t_userName")
private String userName ;
@Column("t_number")
private String number ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@Override
public String toString() {
return "Filter [id=" + id + ", userName=" + userName + ", number=" + number + "]";
}
}
测试【不会反射的小伙伴自行补充知识吧】
package t3_02;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Filter filter = new Filter();
filter.setId(1);
filter.setUserName("Anne");
String sql = getSql(filter);
System.out.println(sql);
}
static private String getSql(Filter f) {
StringBuilder sb = new StringBuilder();//拼接sql
Class<?> c = f.getClass();
boolean isExist = c.isAnnotationPresent(Table.class);//这个类是否有这个注解@Table
if(!isExist) {//没有则停止
return null ;
}
Table table = (Table) c.getAnnotation(Table.class);//获得这个注解的类
String tableName = table.value();//获取注解的值 【与表的名字对应】
sb.append("select * from ").append(tableName).append(" where 1=1");
Field[] fArray = c.getDeclaredFields();//获取所有类型【共有、私有...】的字段
for(Field field : fArray) {
// field.setAccessible(true);
boolean isExist1 = field.isAnnotationPresent(Column.class);//这个字段是否有这个注解@Column
if(!isExist1) {
continue ;
}
Column column = (Column) field.getAnnotation(Column.class);//获得这个注解的类
String columnName = column.value();//获取注解的值 【与数据库表字段对应】
String fieldName = field.getName();//获取这个字段的名称
String getMethodName = "get"
+fieldName.substring(0, 1).toUpperCase()
+fieldName.substring(1);//拼接get方法
Object fieldValue = null ;
try {
Method getMethod = c.getMethod(getMethodName);//获取get方法
fieldValue = getMethod.invoke(f);//获取到方法后通过反射调用,获取我们设置的值
if(fieldValue == null) {
continue;
}
if(fieldValue instanceof Integer && !fieldValue.equals(0)) {
sb.append(" and ").append(columnName).append("=").append(fieldValue);
}else if(fieldValue instanceof String) {
sb.append(" and ").append(columnName).append("=").append("'"+fieldValue+"'");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return sb.toString();
}
}
结果:select * from t_user where 1=1 and t_id=1 and t_userName = ‘Anne’