注解
- 它是一种引用数据类型、编译后生成xxxx.class文件
- 自定义注解:[修饰符] @interface 注解类型名{}
- 使用: @注解类型名
- 注解可以出现在:类上、属性上、方法上、注解上、接口上、枚举上、参数列表中、默认情况下可以出现在任意位置
一、jdk内置注解
1、@Override
- 这个注解只能注解方法
- 这个注解是给编译器看的,和运行阶段没有关系
- 凡事java中的方法带有这个注解,编译器都会进行编译检查,如果这个方法不是重写父类的方法,编译器会报错
2、@Target
- 这是一个元注解,用来标注“注解类型”的“注释”
- 这个Target注解用来标注“被标注的注解”可以出现在哪些位置上
- @Target(ElementType.METHOD) 只能出现在方法上
3、@Retention
- 这是一个元注解,用来标注“注解类型”的“注解”
- 这个Retention主角儿用来标注“被标识的注解”最终保存再哪里
- @Retention(RetentionPolicy.SOURCE):保存到java源文件中
- @Retention(RetentionPolicy.CALSS):保存到class文件中
- @Retention(RetentionPolicy.RUNTIME):保存待class文件中,并允许反编译
3、@Deprecated
- 过时注解
- 代表该类或方法已过时
二、自定义注解
1、定义注解接口
- 添加属性
- 设置属性默认值
- 特性:
- 当属性名为value并且只有一个属性时,可以省略属性名称
- 例如 @Myannocation(“xd")
public @interface MyAnnocation {
//颜色
String color();
//注解的使用者 默认xd
String name() default "xd";
}
public class MyTest {
public static void main(String[] args) {
}
@MyAnnocation(color = "red")
public static void a(){
}
}
2、注解中的属性类型
其中如果数组中自由一个元素,则可以省略大括号
- int 【八种数据类型可以以及数组】
- String
- String[]
- enum
- enum[]
- Class
- Class[]
三、获取类上注解信息
- 注解先看类上给的值
- 不看方法上赋得值
1、MyAnnocation
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnocation {
/*设置该类的作用位置
设置该类是否能被反编译
* */
String flag() default "no";
}
2、MyTestAnno
@MyAnnocation(flag = "true")
public class MyTestAnno {
int a;
@MyAnnocation(flag = "xd")
public static void run(){}
}
3、反射获取
public class 反射获取 {
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.xd.注解.通过反射获取注解.MyTestAnno");
//判断这个类上是否有MyAnnocation注解
boolean annotationPresent = aClass.isAnnotationPresent(MyAnnocation.class);
System.out.println(annotationPresent);
if(annotationPresent){
//获取注解对象
MyAnnocation annotation = (MyAnnocation) aClass.getAnnotation(MyAnnocation.class);
System.out.println("当前注解:"+annotation.flag());
}
}
}
输出的结果:
/*
true
当前注解:true
*/
4、获取MyTestAnno方法上的注解信息
public class 获取方法上的注解信息 {
public static void main(String[] args) throws Exception{
Class aClass = Class.forName("com.xd.注解.通过反射获取注解.MyTestAnno");
//获取这个类中的run方法
Method run = aClass.getDeclaredMethod("run");
//获取这个方法上的注解
MyAnnocation annotation = run.getAnnotation(MyAnnocation.class);
//获取这个注解中的值
System.out.println(annotation.flag());//xd
}
}
四、需求
- 注解在开发中有什么用?
- 注解使用来做参考的,铭牌。
- 例如:有一个注解@ID
- 这个注解只能出现在类上面,当这个类上有这个注解的时候
- 要求这个类中必须有一个int类型的id属性。如果没有这个属性就报异常,如果有就正常执行
Id
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Id {
}
MyAnno
@Id
public class MyAnno {
int id;
String name;
String Password;
}
NoIdAnnocation
public class NoIdAnnocation extends RuntimeException{
public NoIdAnnocation() {
}
public NoIdAnnocation(String message) {
super(message);
}
}
MyTest
public class MyTest {
public static void main(String[] args)throws Exception {
Class aClass = Class.forName("com.xd.注解.需求.MyAnno");
boolean flag=false;
if(aClass.isAnnotationPresent(Id.class)){
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
if("id".equals(declaredField.getName())&& "int".equals(declaredField.getType().getSimpleName())){
flag=true;
break;
}
}
}
if(!flag){
throw new NoIdAnnocation("拥有@id注解的类必须要拥有int id属性");
}
}
}