注解
Jdk1.5之后的新特性
jdk默认的注解,可以用于doc文档的生成
删除package,执行javadoc xxx.java,就能生成文档
//package com.company;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws Exception {
}
/**
* 计算俩
* @parama整数
* @paramb整数
* @return 俩数字的和
public int add(int a,int b){
return a+b;
}
}
作用分类
编写文档,通过代码表示的注解生成文档
代码分析:通过代码标识的注解对代码进行分析(反射)
编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查(@override)
jdk中预定义的一些注解
@override:检测被该注解标注的方法是否是继承父类的
@Deprecated:该注解标注的内容,已经过时(date当中的很多方法就是过时的方法)
@Suppresswarnings压制警告:可以用来压制ide的警告传参"all"可以压制所有的警告,卸载类上面可以压制整个类的所有警告
自定义注解
格式
public @interface MyAnno {}
编译成字节码之后
public interface MyAnno extends java.lang.annotation.Annotation{}
注解本质上就是一个接口,继承了Annotation
属性,接口中可以定义的成员方法
要求:只能返回以下类型
- 基本数据类型
- String
- 枚举
- 注解
- 以上类型的数组
定义了属性,在使用时需要给属性赋值
1.如果定义属性时,使用default关键字给默认初始化,则使用注解时,可以不进行属性的赋值
2.如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
3.数组赋值时,值使用大括号包裹,如果数组中就一个值,大括号可以省略不写
Main.java
package com.company;
public class Main {
@MyAnno(value=12,anno2=@MyAnno2,strs={"123","!@3","awe"})
public static void main(String[] args) {
}
}
MyAnno2.java
package com.company;
public @interface MyAnno2 {
}
package com.company;
public @interface MyAnno {
int value();
MyAnno2 anno2() ;
String []strs();
}
元注解
用于描述注解的注解
@Target:描述注解能够作用的位置
参数:枚举类型的数组
TYPE:可以作用于类上
METHOD:可以作用于方法上
FIELD:可以作用于成员变量上
以上几个可以并存可以用逗号分隔开放在数组中
@Retention:描述注解被保留的阶段
参数,枚举类
SOURCE编译阶段 连字节码当中都不会存在
CLASS类对象阶段 会保留到字节码文件中,但不会被java虚拟机读取到
RUNTIME阶段 自己定义的一半使用这个注解:当前被描述的注解会保留到class字节码中并被jvm读取到
@Documeted:描述注解是否被抽取到api文档中
加了注解表示这个注解描述的信息可以被抽取到java doc文档
@Innherited:描述注解是否被子类继承
这个注解会自动的被子类继承,被该注解修饰的父类,其子类会自动继承他的注解
Main.java
package com.company;
@MyAnno(value=12,anno2=@MyAnno2,strs={"123","!@3","awe"})
public class Main {
// @MyAnno(value=12,anno2=@MyAnno2,strs={"123","!@3","awe"}) 这样写会报错
public static void main(String[] args) {
}
}
注解类
package com.company;
@MyAnno(value=12,anno2=@MyAnno2,strs={"123","!@3","awe"})
public class Main {
// @MyAnno(value=12,anno2=@MyAnno2,strs={"123","!@3","awe"}) 这样写会报错
public static void main(String[] args) {
}
}
在程序中使用解析注解
在程序中使用(解析)注解:获取注解中定义的属性值
Sxtable.java 作用在类上面的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sxtable {
String value();
}
Zhujie.java
作用在类属性上的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})//作用在成员变量之上
@Retention(RetentionPolicy.RUNTIME)//保留到运行时阶段
public @interface Zhujie {
String columName();
String type();
int length();
}
User.java 模型类
@Sxtable("tb_user")
public class User {
@Zhujie(columName = "id",type="int",length = 11)
private int id;
@Zhujie(columName = "name",type = "int",length = 16)
private String name;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
Main
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) {
System.out.println("------");
try {
Class clazz=Class.forName("User");
Annotation[] annotations = clazz.getAnnotations();//获取这个类所有的注解
for (Annotation a:annotations){
System.out.println(a);//@Sxtable(value=tb_user)
}
Sxtable st = (Sxtable) clazz.getAnnotation(Sxtable.class);//获取指定的注解
System.out.println(st);//@Sxtable(value=tb_user)
//获得类属性的注解
Field f=clazz.getDeclaredField("name");
Zhujie zj = f.getAnnotation(Zhujie.class);
System.out.println("name:"+zj.columName()+"\nlenth:"+zj.length()+"\ntype:"+zj.type());
//name:name
//lenth:16
//type:int
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}