Java注解
1. 常见的内置注解
@Override
只能修饰方法,表示对父类的方法进行重写
@Deprecated
可以修饰方法、属性、类,表示这些元素不鼓励程序员使用
@SuppressWarnings
可以修饰方法、类,用来抑制警告
常见参数:
deprecation -> 使用过时方法的警告
unchecked -> 执行了未检查的转换时的警告,如使用集合没指定泛型
all -> SuppressWarnings中定义的所有警告
参数使用:@SuppressWarnings(“unchecked”)
@SuppressWarnings(value = {“unchecked”, “deprecation”})
2. 元注解
元注解可以理解为注解的解释。
常用元注解:
@Target – 注解用于什么地方,默认为全部
参数:
● ElementType.CONSTRUCTOR: 用于描述构造器
● ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE: 用于描述局部变量
● ElementType.METHOD: 用于描述方法
● ElementType.PACKAGE: 用于描述包
● ElementType.PARAMETER: 用于描述参数
● ElementType.TYPE: 用于描述类、接口(包括注解类型) 或enum声明
@Retention – 什么时候使用该注解
参数:
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
3. 自定义注解
TableAnnotation.java
package annotation;
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 TableAnnotation {
/*
* String -> 类型
* value -> 变量名
*/
String value() /* default "" */; // default可以指定默认值
}
FieldAnnotation.java
package annotation;
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 FieldAnnotation {
String columnName(); // 字段名
String type(); // 类型
int length(); // 长度
}
Student.java
package annotation;
@TableAnnotation("StudentTable")
public class Student {
@FieldAnnotation(columnName = "ID", type = "int", length = 10)
private int id;
@FieldAnnotation(columnName = "Sname", type = "varchar", length = 10)
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ReadAnnotation.java
package annotation;
import java.lang.reflect.Field;
/*
* 利用反射机制读取注解
*/
public class ReadAnnotation {
private static void getFieldAnnotation(Class clazz, String field) throws NoSuchFieldException, SecurityException {
Field f = clazz.getDeclaredField(field);
FieldAnnotation fieldAnnotation = f.getAnnotation(FieldAnnotation.class);
System.out.println("字段名: " + fieldAnnotation.columnName()
+ ", 类型: " + fieldAnnotation.type()
+ ", 长度: " + fieldAnnotation.length());
}
public static void main(String[] args) {
try {
// 获取Student类的信息
Class clazz = Class.forName("annotation.Student");
// 获取Student的类的注解
TableAnnotation tableAnnotation = (TableAnnotation) clazz.getAnnotation(TableAnnotation.class);
System.out.println("表名: " + tableAnnotation.value());
// 获取Student的属性id的注解
getFieldAnnotation(clazz, "id");
// 获取Student的属性name的注解
getFieldAnnotation(clazz, "name");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
表名: StudentTable
字段名: ID, 类型: int, 长度: 10
字段名: Sname, 类型: varchar, 长度: 10