赞
踩
注解:就是具有特殊含义的标记(注解是给机器阅读的)
作用:对Java中类、方法、成员变量做标记,然后进行特殊处理,至于到底做何种处理由业务需求来决定。
注解就是在代码里添加一些特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行操作。
注解与注释不同,会影响程序的执行,而注释不会。
使用过的注解:
定义注解使用关键字:@interface
public @interface 注解名{
//内容
}
注解本质上就是一个接口。所有注解都会继承一个接口:Annotation
public interface 自定义注解名 extends java.lang.annotation.Annotation {}
public @interface Student {
String name(); // 姓名
int age() default 18; // 年龄
String gender() default "男"; // 性别
}
// 该注解就有了三个属性:name,age,gender
- 八种基本数据类型(int,short,long,double,byte,char,boolean,float)
- String,Class,注解类型,枚举类
- 以上类型的一维数组形式
//无属性注解
@注解名 例:@Test
//有属性注解
@注解名(属性=值,属性=值)
注解可以在类上,成员变量上,构造方法上,方法上,参数上…
有默认值的属性,可以不用进行赋值。
案例:
public @interface Book {
String name();
double price() default 100.0;
String[] author();
}
建立一个BookStore的类,在类中定义成员变量,构造方法,成员方法
@Book(name = "西游记", author = {"吴承恩", "张三"})
public class BookStore {
@Book(name = "三国", price = 10, author = {"罗贯中"})
private String book;
@Book(name = "三国", price = 10, author = {"罗贯中"})
public BookStore() {
}
@Book(name = "三国", price = 10, author = {"罗贯中"})
public void test() {
}
}
如果注解中只有一个属性要赋值,而且名字是value,可以将value给省略,可以直接给值。
默认情况下,注解可以用在任何地方,比如类,成员方法,构造方法,成员变量等地方
如果要限制自定义注解的使用位置怎么办?那就要学习一个新的知识点:元注解
结论:元注解是用来约束自定义注解的使用范围、生命周期。
常用元注解:@Target、@Retention
@Target
@Retention
元注解的使用:
@Target({ElementType.METHOD,ElementType.TYPE}) //元注解
@interface Stu{
String name();
}
//类
@Stu(name="jack") //成功
public class AnnotationDemo02 {
// 成员变量
@Stu(name = "lily") // 编译失败
private String gender;
// 成员方法
@Stu(name="rose") //成功
public void test(){
}
// 构造方法
@Stu(name="lucy") // 编译失败
public AnnotationDemo02(){}
}
获取注解数据的原理:
想要对注解中的数据进行解析,需要借助:AnnotatedElement
接口
AnnotatedElement
接口AnnotatedElement
是一个接口,定义了解析注解的方法:
1. boolean isAnnotationPresent(Class<Annotation> annotationClass)
判断当前对象是否使用了指定的注解,如果使用了则返回true,否则false
public class BookStore{
@Book(name="书名")
public void buy() // Method对象 判断该对象上是否使用了@Book注解
{ // boolean flag = Method对象.isAnnotationPresent(Book.class)
}
}
2. T getAnnotation(Class<T> annotationClass)
根据注解类型获得对应注解对象
// 获取注解的具体值见下面的综合案例
// 获取对象上的自定义注解
// Book bookAnno = Method对象.getAnnotation(Book.class);
// bookAnno.属性 //获取注解中属性的值
Class,Constructor,Method,Field都会实现AnnotatedElement 接口
注解解析的步骤:(注解是书写在:类、方法、变量上)
1、利用反射技术获取注解作用的对象:类、方法、变量、构造方法
2、判断对象上是否有自定义注解存在
3、有:获取对象上的自定义注解
4、使用获取到的自定义注解对象,拿到注解中的属性值
注意:注解解析必须保证自定义注解生命周期在RUNTIME(程序运行中)
案例:
需求如下:
- 定义注解Book,要求如下:
- 包含属性:String value() 书名
- 包含属性:double price() 价格,默认值为 100
- 包含属性:String[] authors() 多位作者
- 限制注解使用的位置:类和成员方法上 【Target】
- 指定注解的有效范围:RUNTIME 【Retention】
- 定义BookStore类,在类和成员方法上使用Book注解
- 定义TestAnnotation测试类获取Book注解上的数据
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE}) //使用范围:方法、类
@Retention(RetentionPolicy.RUNTIME) //保证注解在程序执行时有效(适用于注解解析)
public @interface Book {
String value();
double price() default 100;
String[] authors();
}
//类
public class BookStore {
@Book(value = "Java入门", authors = {"张老师", "毕老师"})
public void buy() {
System.out.println("购书.....");
}
}
//对注解中的数据进行解析
public class TestBookStore {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//反射套路:1、Class 2、构造器 3、Method
Class<BookStore> bookStoreClass = BookStore.class;
//获取构造器
Constructor<BookStore> con = bookStoreClass.getConstructor();
BookStore bookStore = con.newInstance();//实例化对象
//获取Method
Method method = bookStoreClass.getMethod("buy");
//解析注解的步骤
if(method.isAnnotationPresent(Book.class)){
//获取Method对象上的Book注解
Book bookAnno = method.getAnnotation(Book.class);
//获取注解上的数据
String bookName = bookAnno.value();
double bookPrice = bookAnno.price();
String[] bookAuthors = bookAnno.authors();
System.out.println("书名:"+bookName);
System.out.println("价格:"+bookPrice);
System.out.println("作者:"+ Arrays.toString(bookAuthors));
}
}
}
小结
注解解析的步骤:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。