什么是注解(Annotation)
Annotation:是JDK5.0开始引入的新技术
Annotation的作用:不是程序本身,可以对程序作出解释可以被其程序读取。(注解信息处理流程是注解和注释的最大区别)
Annotation的格式:“@注释名”在代码中存在 例如 @SuppressWarning(value=“all”)
Annotation的使用位置:可以加在package,class,method,filed等上面,相当于添加了额外的辅助信息,可以利用反射机制编程实现对这些元素数据的访问。
内置注解
1.@Override 此注释只适用于修饰方法,表示一个方 法声明打算重写超类中的另一个方法声明。
2.@Deprecated 此注释可用于修饰方法、属性、类 ,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更 好的选择。
3.@SuppressWarnings –用来抑制编译时的警告信息 。 – 与前两个注释有所不同,你需要添加一个参数才能正确使用。
例如:
@SuppressWarnings(“unchecked”) 执行未检查的转换时的警告
@SuppressWarnings(value={“unchecked”, “deprecatio”}) 执行未检查的转换时的警告与使用了过时的方法警告。
元注解(负责注解其他注解)
– @Targe: 被描述的注解可以用在什么地方
ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
ElementType.FIELD:允许作用在属性字段上
ElementType.METHOD:允许作用在方法上
ElementType.PARAMETER:允许作用在方法参数上
ElementType.CONSTRUCTOR:允许作用在构造器上
ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
ElementType.ANNOTATION_TYPE:允许作用在注解上
ElementType.PACKAGE:允许作用在包上
– @Retention:描述注解的生命周期,一般我们用RUNTIME,即运行时有效。
RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
RetentionPolicy.RUNTIME:永久保存,可以反射获取
自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
要点: – @interface用来声明一个注解
@Target(value={
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table{
String value();
}
注意: 注解元素必须要有值。我们定义注解元素时,经常使用空字符串、0作为默认值。 也经常使用负数(比如:-1)表示不存在的含义
使用反射机制读取注解
案例:
给Student加上对应的注解,然后通过反射读取注解内容,自动生成SQL语句,创建表
创建注解一 SxtField,用来读取字段名,字段类型以及字段长度
@Target(value={
ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtField {
String columName();//定义字段名字
String type();//定义字段类型
int length();//定义字段长度
}
创建注解二 Table,用于返回要创建的表名
@Target(value={
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table{
String value();
}
创建对应的学生类
@Table("tb_student") // 数据库对应的表名
public class Student {
@SxtField(columName = "id", type = "int", length = 10)
private int id;
@SxtField(columName = "sname", type = "varchar", length = 10)
private String sname;
@SxtField(columName = "age", type = "int", length = 3)
private int age;
public Student(int id, String sname, int age) {
super();
this.id = id;
this.sname = sname;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
}
}
利用反射读取注解信息,模拟处理注解信息的流程
public class Test {
public static void main(String[] args) {
try {
Class c = Class.forName("Annotation.Student");
// 获得类的所有有效注解
Annotation[] annotations = c.getAnnotations();
for (Annotation a : annotations) {
System.out.println(a);
}
// 获得类的指定的注解
Table t = (Table) c.getAnnotation(Table.class);
System.out.println(t.value());
// 获得类的属性的注解
Field f = c.getDeclaredField("sname");
SxtField F = f.getAnnotation(SxtField.class);
String str1=F.columName() + " " + F.type() + "(" +F.length()+"),";
System.out.println(str1);
f=c.getDeclaredField("id");
F=f.getAnnotation(SxtField.class);
String str2=F.columName() + " " + F.type() + "(" +F.length()+"),";
System.out.println(str2);
f=c.getDeclaredField("age");
F=f.getAnnotation(SxtField.class);
String str3=F.columName() + " " + F.type() + "(" +F.length()+")";
System.out.println(str3);
// 根据获得的表名、字段的信息,拼出DDL语句,然后,使用JDBC执行这个SQL,在数据库中生成相关的表
String sql="create table "+t.value()+"("+str1+str2+str3+");";
System.out.println(sql);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
感受
学习完注解之后,感觉又打开了一扇新世界的大门脑袋里突然有个花里胡哨的想法。(关于毕业设计)
使用自己写的WebServer容器,作为项目的服务器
使用自己写的简单的MVC框架,为项目提供各种映射关系
使用反射读取注解,拼出DDL语句,完成对数据库的操作
前路未知,充满挑战