一、注解的概念
1.注解是一种引用数据类型,编译之后生成xxx.class文件
2.自定义注解的格式:[修饰符列表] @interface 注解类型名{}
3.注解的使用:@注解类型名。可以出现在类上,属性上,方法上,变量上,注解类型上
4.JDK内置的注解:java.lang包下的注释类型:
Deprecated:已过时的
Override:重写父类方法(只能注解方法,给编译器进行编译检查,和运行阶段没有关系如果这个方法不是重写父类的方法,编译器报错)
5.标注注解的注解称为元注解,常见的注解有:
Target:表示“被标注的注解”可以出现在哪些位置上
@Target(ElementType.METHOD):表示“被标注的注解”只能出现在java源文件中
Retention:表示“被标注的注解”最终保存在哪里
@Retention(RetentionPolicy.SOURCE):表示该注解被保存在java源文件中
@Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中
@Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制所读取
二、 注解中定义属性
1.属性的使用和默认值
MyAnnotation.java
public @interface MyAnnotation {
/*
名字属性
*/
String name();
/*
颜色属性
*/
String color();
/*
年龄属性
*/
int age() default 25;
}
MyAnnotationTest.java
//除了有默认值的属性,其他属性必须赋值,否则会报错
@MyAnnotation(name = "string", color = "红色")
public class MyAnnotationTest {
}
2.value的省略(只有一个value属性的情况下适用)
OtherAnnotation.java
public @interface OtherAnnotation {
String value();
}
OtherAnnotationTest.java
//当属性只有一个且为value时,在使用注解时可以省略“value =”
@OtherAnnotation("shenyifei")
public class OtherAnnotationTest {
}
3.注解中的属性可以是哪些类型
OtherAnnotation.java:
public @interface OtherAnnotation {
//属性的类型可以是:
// byte short int long
// float double boolean
// char String Class 枚举类型
//以及以上每一种的数组形式
String color();
Season[] seasons();
}
OtherAnnotationTest.java:
@OtherAnnotation(color = "蓝色" ,seasons = {Season.SUMMER,Season.WINTER})
public class OtherAnnotationTest {
//属性如果是数组且数组内元素只有一个的话,可以省略大括号
@OtherAnnotation(color = "蓝色" ,seasons = Season.SUMMER)
public void doSome(){
}
}
三、反射注解
MyAnnotationTest.java:
//除了有默认值的属性,其他属性必须赋值,否则会报错
@MyAnnotation(name = "string", color = "红色", age = 26)
public class MyAnnotationTest {
}
MyAnnotation.java:
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
/*
名字属性
*/
String name();
/*
颜色属性
*/
String color();
/*
年龄属性
*/
int age() default 25;
}
main:
try {
//获取类对象
Class c = Class.forName("com.example.test.MyAnnotationTest");
//判断类上面是否有@MyAnnotation,MyAnnotation.class该注解必须被
// @Retention(RetentionPolicy.RUNTIME)修饰,才能通过反射机制读取到
System.out.println(c.isAnnotationPresent(MyAnnotation.class));
if (c.isAnnotationPresent(MyAnnotation.class)) {
//获取该注解对象
MyAnnotation myAnnotation = (MyAnnotation) c.getAnnotation(MyAnnotation.class);
//获取注解对象的属性
int age = myAnnotation.age();
String color = myAnnotation.color();
System.out.println(age + "," + color);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
自己写的example:
Hobby.java:
public enum Hobby {
SWIM,RUN,SING,DRAW,WRITE
}
MyAnnotation.java:
@Retention(RetentionPolicy.RUNTIME)//别忘!!!!!!!!!!
public @interface MyAnnotation {
String name();
int age();
boolean sex();
Hobby[] hobbies();
}
MyAnnotationTest.java:
public class MyAnnotationTest {
@MyAnnotation(name = "韭韭", age = 22, sex = false, hobbies = {Hobby.SWIM,Hobby.DRAW})
public void m1(){
}
}
main:
try {
Class c = Class.forName("com.example.test.AnnotationTest.MyAnnotationTest");
Method method = c.getMethod("m1");
System.out.println(method.isAnnotationPresent(MyAnnotation.class));
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
int age = annotation.age();
String name = annotation.name();
boolean sex = annotation.sex();
Hobby[] hobbies = annotation.hobbies();
System.out.println(name + "," + (sex ? "男" : "女") + "," + age + ",");
for (Hobby hobby : hobbies) {
System.out.println(hobby);
}
}
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
}
输出:
四、注解的应用
Id.java:
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
IllegalClassException.java:
public class IllegalClassException extends RuntimeException{
public IllegalClassException() {
}
public IllegalClassException(String message) {
super(message);
}
}
User.java:
@Id
public class User {
// int id;
String name;
String no;
}
main:
try {
Class c = Class.forName("com.example.test.AnnotationExample.User");
if (c.isAnnotationPresent(Id.class)){
Field[] fields = c.getFields();
boolean isOk = false;
for (Field field : fields){
if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){
isOk = true;
break;
}
}
if(!isOk){
throw new IllegalClassException("是不符合要求“带有@Id注解的类必须有int类型的id属性”的类");
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
输出: