注解
1.1 定义
注释:对代码的解释和说明,注释是给程序员看的。
注解:对代码的解释和说明,注解是程序看的。
1.2 常见注解
@Override 检测方法是否是重写
@Deprecated 表示该方法已过期
@SuppressWarnings("all") 压制警告
1.3 自定义注解
语法:
@元注解
public @interface 注解名 {
数据类型 属性名();
数据类型 属性名() default 默认值;
}
1.4 元注解
注解的注解就是元注解
1.4.1 @Retention
定义该注解作用什么时候
-
SOURCE
-
CLASS
-
RUNTIME
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
1.4.2 @Target
定义的是该注解的作用范围,你能够添加在什么位置
-
TYPE : 能添加在类上
-
FIELD : 能添加在属性上
-
METHOD : 能添加在方法上
-
PARAMETER : 能添加在方法的参数上
-
ANNOTATION_TYPE : 能添加在注解上
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
1.4.3 @Documented
规定该注解在生产API文档时,存不存在
1.4.4 @Inherited
子类继不继承父类的注解
package com.qfedu;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited //添加注解的类的子类会继承该注解
@Documented //生成API文档时,该注解也会被生成
@Retention(RetentionPolicy.RUNTIME) //定义作用到的时机
@Target({ElementType.FIELD, ElementType.TYPE}) //注解的添加范围
public @interface MyAnno {
}
1.5 属性
1.5.1 数据类型
String,基本类型,枚举,一维数组
1.5.2 规则
在使用该注解时,必须为属性赋值,重复为该属性定义默认值
package com.qfedu;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface YourAnno {
/*
* 注解中可以定义属性
*
* 数据类型 属性名();
*
* 在使用该注解时,必须为属性赋值,除非有默认值
*/
String name();
int age() default 18;
Gender gender();
String[] hobby();
}
package com.qfedu;
@YourAnno(name="heheda", age=18, gender=Gender.BOY, hobby={"jj","yy"})
@MyAnno
public class Student {
@MyAnno
private String name;
@YourAnno(name="heheda", gender=Gender.BOY, hobby={"jj","yy"})
public void play(String friend) {
System.out.println(name+"和"+friend+"一起玩");
}
}
1.5.3 特殊情况
如果在一个注解中只有一个属性,且该属性名为value,那么就可以在赋值时,不用定义属性名,直接赋值
-
数据类型如果不是数组 @注解(值)
-
数据类型是数组
-
@注解(值) 如果只有一个值,会自定把值放到数组中
-
@注解({值1,值2}) 如果有多个值,则必须放到大括号中
-
package com.qfedu;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface HerAnno {
// String value();
String[] value();
}
package com.qfedu;
@YourAnno(name="heheda", age=18, gender=Gender.BOY, hobby={"jj","yy"})
@MyAnno
public class Student {
@MyAnno
private String name;
// @HerAnno("jackma")
@HerAnno({"jackma","pony"})
@YourAnno(name="heheda", gender=Gender.BOY, hobby={"jj","yy"})
public void play(String friend) {
System.out.println(name+"和"+friend+"一起玩");
}
}
1.6 注解的使用
注解一定要反射一起使用,才能达到效果
package com.qfedu;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface HisAnno {
String value();
}
package com.qfedu;
@YourAnno(name="heheda", age=18, gender=Gender.BOY, hobby={"jj","yy"})
@MyAnno
public class Student {
@HisAnno("特拉斯")
@MyAnno
private String name;
// @HerAnno("jackma")
@HerAnno({"jackma","pony"})
@YourAnno(name="heheda", gender=Gender.BOY, hobby={"jj","yy"})
public void play(String friend) {
System.out.println(name+"和"+friend+"一起玩");
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
}
package com.qfedu;
import java.lang.reflect.Field;
public class Demo02 {
public static void main(String[] args) throws Exception {
/*
* 获取一个Student对象,name属性值为@HerAnno注解的value属性值
*/
Class<?> clazz = Class.forName("com.qfedu.Student");
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
Object obj = clazz.newInstance();
//获取该属性的注解(@HisAnno)
HisAnno anno = field.getAnnotation(HisAnno.class);
//获取该注解的属性值
String name = anno.value();
field.set(obj, name);
System.out.println(obj);
}
}
自定义一个注解
-
作用时机整个生命周期
-
作用范围为方法
-
定义一个属性 名value 类型为String
把这个注解添加到Student中play方法上,把value值赋值给参数friend,然后调用该方法