Java注解全解
什么是Java注解?
注解(也被成为元数据)为我们在代码中添加信息提供一种形式化的方法,使我们在稍后某个地方可以方便地使用这些数据(如使用反射的方法使用)。
推荐一个简单易懂的教程
注解的分类
按来源
-
标准注解
@Override 表示当前的方法将覆盖超类的方法
@Deprecated 中文意思是弃用,如果在其他地方使用了为它的元素,那么编译器会发出警告信息
@SuppressWarnings 关闭编译器的警告信息,如你使用了被@Deprecated的元素,可以用此注解关闭警告的信息
-
元注解(即注解的注解在自定义注解中会用到)
@Target 表示该注解可以用于什么地方 可能的参数有
- ElementType.CONSTRUCTOR:构造器的声明
- ElementType.FIELD:域声明
- ElementType.LOCAL_VARIABLE:局部变量声明
- ElementType.METHOD:方法声明
- ElementType.PACAKAGE:包声明
- ElementType.PARAMENTER:参数声明
- ElementType.TYPE:类、接口、enum声明
@Retention 表示需要在什么时候在什么时候保存该编译信息
- SOURCE 将被编译器弃用
- CLASS 在class中可用,但会被VM弃用
- RUNTIME 在运行期间也保留注解,因此可以通过反射机制读取注解的信息
@Documented
- 该注解包含在Javadoc中
@Inherited
- 允许子类继承父类的注解
- 自定义注解(后面通过举例展示)
按照运行机制
- 源码注解 注解只在源码中存在
- 编译时注解 注解在源码和.class中均存在
- 运行时注解 VM将在运行期也保留注解,可以通过反射机制读取注解的信息
实战(自动生成MySQL语句)
注解的定义
package iMooc;
import ...
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
public String value();
}
package iMooc;
import ...
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
public String value();
}
注解的定义和接口很像,使用@Interface,内部是元数据,当只有一个元数据是名字应叫做value
使用注解
package iMooc;
@Table("user")
public class Filter {
@Column("id")
private int id;
@Column("user_name")
private String Username;
@Column("age")
private int age;
public Filter(int id, String username, int age) {
this.id = id;
Username = username;
this.age = age;
}
public Filter(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return Username;
}
public void setUsername(String username) {
Username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
编写注解处理器
public class Test {
public static void main(String[] args){
testMooc();
}
private static void testMooc() {
Filter filter=new Filter(1,"不咸",20);
System.out.print(query(filter));
}
private static String query(Filter filter){
StringBuilder sb=new StringBuilder();
//获得实例的类
Class c=filter.getClass();
//判断是否有注解
boolean exist=c.isAnnotationPresent(Table.class);
if (!exist) return null;
//获得注解,在table.value()获得参数
Table table= (Table) c.getAnnotation(Table.class);
//拼装MySQL语句
sb.append("select * from ").append(table.value()).append("where 1=1");
//获得字段既变量名
Field[] fArray=c.getDeclaredFields();
for (Field field:fArray){
//根据字段获得表名
boolean exits=field.isAnnotationPresent(Column.class);
if (!exist) return null;
Column column=field.getAnnotation(Column.class);
String columnName=column.value();
//获得字段值
String fieldName=field.getName();
String methodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
Object value=null;
try {
Method method=c.getMethod(methodName);
value= (Object) method.invoke(filter,null);
} catch (Exception e) {
e.printStackTrace();
}
//拼装SQL语句
if (value!=null){
if (value instanceof Integer)
sb.append(" and ").append(fieldName).append("=").append(value);
else sb.append(" and ").append(fieldName).append("= '").append(value).append("'");
}
}
return sb.toString();
}
}