注解
annotation:只有被解析时才具有意义
作用
1、不是程序本身,但可以对程序作出解释。(这一点和注释没区别)
2、可以被其他程序(比如:编译器等)读取(注解和注释的区别)
在哪里使用
可以附加在packet、class、method、fild等上面,相当于给他们添加了额外的辅助信息,可以通过反射机制编程实现对元数据的访问。
注解的完整使用
①、定义注解
②、在类中使用注解
③、通过解析程序读取注解进行解析处理(一个班工作中都是通过框架来完成)
注解作业
ORM(Object Relationship Mapping)
1、java类和数据库的映射关系
2、类和表结构对应
3、属性和字段对应
4、对象和记录对应
反射操作注解
步骤:
①、获取对应类或者类的方法或者类的属性的Class对象
②、通过Class对象.getAnnotation(”注解名”)方法获取注解
Demo代码
/**
* @auther TongFangPing
* @date 2019/10/14 22:53.
* 使用反射读取注解的信息
* 通过反射获取类、类的属性、累的方法中的注解,可以用来拼接成SQL语句。
*/
public class Demo {
public static void main(String[] args) {
try {
//反射获取Class对象
Class claz=Class.forName("com.annotate.study.Student");
//获取Student类的所有注解
Annotation[] annotations=claz.getAnnotations();
for (Annotation aos:annotations
) {
System.out.println(aos);
}
//获取类的指定注解
TableAnnotation tban= (TableAnnotation)claz.getAnnotation(TableAnnotation.class);
System.out.println(tban.value());
//获得类的属性的注解
Field field =claz.getDeclaredField("name");
FileldAnnotation fdAn=field.getAnnotation(FileldAnnotation.class);
System.out.println(fdAn.columnName()+"--"+fdAn.type()+"--"+fdAn.length());
//根据获得的表名、字段的信息、拼出SQL语句,使用JDBC执行,生成数据表
} catch (Exception e) {
e.printStackTrace();
}
}
}
内置注解
①、@Override:重写超类方法
②、Deprecated:修饰过时的类、方法、属性等
③、SuppressWarnings:抑制编译时的警告信息
自定义注解
- 定义新的 Annotation 类型使用 @interface 关键字
- 自定义注解自动继承了java.lang.annotation.Annotation接口
- Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明。其
方法名和返回值定义了该成员的名字和类型。我们称为配置参数。类型只能
是八种基本数据类型:String类型、Class类型、enum类型、Annotation类型、
以上所有类型的数组。 - 可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字
- 如果只有一个参数成员,建议使用参数名为value
- 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是“参数名 = 参数值”,如果只有一个参数成员,且名称为value,可以省略“value=”
- 没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation
注意:自定义注解必须配上注解的信息处理流程(反射)才有意义。
一、元注解(Target)
Target:用于描述注解的使用范围(即:规定被描述的注解可以用在什么地方)
1、Package包:PACKAGE
2、类、接口、枚举、Annotation:Type
3、CONSTRUCTOR(描述构造器)、FIELD(用于描述域)、METHOD(描述方法)
4、方法参数和本地变量:LOCAL、VARIANBLE(用于描述局部变量)、PARAMETER(用于描述参数)
5、例如:@Target(value= ElementType.METHOD)//范围用于方法
二、元注解:Retention
对现有注解进行解释说明的注解
注解保留策略:描述注解的生命周期
1、SOURCE:在源文件中有效(在源文件中保留)编译器、加载器使用
例如:
public @interface MyInterface {
@Retention(RetentionPolicy.SOURCE)
//这个注解表示让MyInterface注解只能在java源文件中存在,编译成.class文件后注解就不存在了
@Retention(RetentionPolicy.CLASS)
//这个注解的意思是让MyInterface注解在java源文件(.java文件)中存在,编译成.class文件后注解也还存在
Retention注解括号中的"RetentionPolicy.RUNTIME"意思是让MyInterface这个注解的生命周期一直程序运行时都存在
}
三、继承:java.lang.annotation.Annotation接口
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
四、要点
1、@interface用来声明一个注解格式为:public @interface 注解名(自定义体)
2、其中的每一个方法实际上是声明了一个配置参数。
* 方法名为参数的名称
* 返回值类型就是参数的类型(返回类型只能是基本类型、Class、String、enum)
* 可以通过default来声明参数的默认值
* 如果只有一个参数、一般参数名为value
Demo代码
/**
* @auther TongFangPing
* @date 2019/10/14 18:47.
* 自定义注解:MyAnnotation和MyAnnotation2
*/
@Target(value= ElementType.METHOD)//范围用于方法
@Retention(RetentionPolicy.RUNTIME)//保留策略
public @interface MyAnnotation {
//注解参数
String getName() default "";
int getNumber() default 0;
String[]names() default {"扒鸡1号","扒鸡2号","扒鸡3号"};
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})//范围用于方法、类、接口
@interface MyAnnotation2 {
//当注解的属性只有一个时,一般将属性名(参数名)定义为value
String value();
}
/**
*
* 使用自定义注解
*/
@MyAnnotation2(value = "扒鸡")
public class Diyannotate {
@MyAnnotation(getName = "扒鸡1号",getNumber = 1,names = {"扒鸡1号","阿黄","小郑"})
void Test(){
}
}
/**
* 自定义注解:TableAnnotation
*/
@Target(value = ElementType.TYPE)//范围了为类
@Retention(RetentionPolicy.RUNTIME) //保留策略为运行时
public @interface TableAnnotation {
String value();
}
/**
* 自定义注解:FileldAnnotation
*/
@Target(value = ElementType.FIELD) //范围为类的实例域
@Retention(RetentionPolicy.RUNTIME) //保留策略为运行时
public @interface FileldAnnotation {
String columnName();
String type();
int length();
}
/**
* @auther TongFangPing
* @date 2019/10/14 22:32.
* 注解的完整使用:
* 1、定义注解
* 2、在类中使用注解
* 3、通过解析程序读取注解进行解析处理(一般工作当中都是通过框架来完成)
*/
@TableAnnotation("tb_student")
public class Student {
@FileldAnnotation(columnName = "id",type = "int",length = 10)
private int id;
@FileldAnnotation(columnName = "shame",type = "Varchar",length = 10)
private String name;
@FileldAnnotation(columnName = "age",type = "int",length = 3)
private int age;
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}