1.1 什么是注解
- Annotation是从JDK5.0开始引入的新技术
- Annotation的作用:
- 不是程序本身,可以对程序作出解释(类似于注释(comment))
- 可以被其它程序(比如:编译器等)读取
- Annotation的格式:
- 注解是以"@注释名"在代码中存在的,还可以添加一些参数值
- 例如:
@SuppressWarnings(value="unchecked")
- Annotation在哪里使用?
1.2 内置注解
作用在代码的注解是
- @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
- @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
- @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
1.3 元注解
作用在其他注解的注解(或者说 元注解)是:
- @Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。
- @Documented - 标记这些注解是否包含在用户文档中。
- @Target - 标记这个注解应该是哪种 Java 成员。
- @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
1.4 从 Java 7 开始,额外添加了 3 个注解:
- @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
- @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
- @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
1.5 自定义注解
- 使用@interface自定义注解时,自动继承了Java.lang.annotation.Annotation接口
- 分析
[@interface](#)
用来声明一个注解,格式:public @interface 注解名{定义内容}
- 其中的每一个方法实际上就是声明了一个配置参数
- 方法的名称就是参数的名称
- 返回值类型就是参数的类型(返回值只能是基本类型,class、string、enum)
- 可以通过default来声明参数的默认值
- 如果只有一个参数成员,一般参数名为value
- 注解元素必须要有值,我们定义注解元素时,经常使用空字符串、0作为默认值
public class Test02 {
/**
* 注解可以显示赋值,如果没有默认值,就必须给注解赋值
*/
@MyAnnotation2(name = "Hello")
public void test(){};
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
//注解的参数:参数类型 + 参数名();
String name() default "";
int age() default 0;
int id() default -1;//如果默认值为-1,表示不存在
String[] schools() default {"A","B"};
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String value();
}
1.6 ORM
- Object Relationship Mapping
- 类和表结构对应
- 属性和字段对应
- 对象和记录对应
- 利用注解和映射完成类和表结构的映射
public class Test11 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("study.reflection.Student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解的value的值
tableTest tabletest = (tableTest)c1.getAnnotation(tableTest.class);
String value = tabletest.value();
System.out.println(value);
//获得类指定的注解
Field name = c1.getDeclaredField("name");
FieldTest annotation = name.getAnnotation(FieldTest.class);
System.out.println(annotation.columnName());
System.out.println(annotation.length());
System.out.println(annotation.type());
}
}
@tableTest("db_student")
class Student2 {
@FieldTest(columnName = "db_name",type="varchar",length=3)
private String name;
@FieldTest(columnName = "db_id",type="int",length=10)
private int id;
@FieldTest(columnName = "db_age",type="int",length=10)
private int age;
public Student2() {
}
public Student2(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student2{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
/**
* @author zhao
* 类名的注解
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface tableTest{
String value();
}
/**
* @author zhao
* 属性的注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldTest{
String columnName();
String type();
int length();
}