- 注解,也叫注释,英文:Annotation
- 注解是一种引用数据类型,变异之后也是生成.class文件。
- 注解可以出现在类上,属性上,方法上,变量上,注解类型上…
- 注解的使用语法格式:
二、JDK内置的注解:@注解类型名
@Deprecated:
被该注解标注的代码表示已过时,不建议用了。
@Override:
被该注解标注的方法必须是重写父类的方法。否则编译报错。
- 用来标注“注解”的注解,叫元注解。
- 常见元注解:
@Target():用来标注“被标注的注解”可以出现在哪些位置上。
例如:
@Target(ElementType.METHOD)表示“被标注的注解”只能出现在方法上。
@Target({ElementType.TYPE,ElementType.METHOD})表示“被标注的注解”只能出现在类和方法上。
@Retention():用来标注“被标注的注解”最终保存在哪里。
例如:
@Retention(RetentionPolicy.SOURCE)表示该注解只被保留在java源文件中。
@Retention(RetentionPolicy.CLASS)表示该注解被保存在Class文件中。
@Retention(RetentionPolicy.RUNTIME)表示该注解可以被反射机制读取。
- 自定义注解语法格式:
[修饰符列表] @interface 注解类型名{
}
- 示例:
public class Test{
@MyAnnotation(name = "zhangsan",a={1,2,3,4},b=season.Autunm)
public void doSome(){
}
}
@interface MyAnnotation{//注解
String name();//注解属性
int age() default 0;//注解属性
double[] a();//注解属性
season b();//注解属性
}
enum season{Spring, Summer, Autunm, Winter}//枚举
(1)如果一个注解中有属性,那么必须给属性赋值。格式:属性名=值
(2)如果注解中的属性已经default指定了默认值,可以不用给属性赋值。
(3)如果注解中只有一个属性,并且属性名是value,那么属性名可省略。
(4)注解可以是数组。
@Retention(RetentionPolicy.RUNTIME)表示该注解可以被反射机制读取。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@MyAnnotation(name = "zhangsan",a={1,2,3,4},b=season.Autunm)
public class Test{
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("Test");
if (c.isAnnotationPresent(MyAnnotation.class)){//判断类上是否有这个注解
MyAnnotation myAnnotation = (MyAnnotation) c.getAnnotation(MyAnnotation.class);//获取该注解
String name = myAnnotation.name();
season sea = myAnnotation.b();
System.out.println(sea);
}
}
}
@Retention(value = RetentionPolicy.RUNTIME)//必须加这个元注解,否则注解不能被反射机制读取,就无法通过反射获取注解
@interface MyAnnotation{//注解
String name();//注解属性
int age() default 0;//注解属性
double[] a();//注解属性
season b();//注解属性
}
enum season{Spring, Summer, Autunm, Winter}//枚举
六、注解应用:
- 需求:
假设有这样一个注解@Id,当类上有这个注解的时候,要求这个类中必须有一个int类型的id属性,如果没有就会报错,有的话正常。 - 代码:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
@Target(ElementType.TYPE)//元注解,用于规定Id注解只能出现在类上
@Retention(RetentionPolicy.RUNTIME)//元注解,用于规定Id注解可以被反射机制读取
@interface Id{
}
@Id
class Test1{
}
public class Test{
public static void main(String[] args) throws ClassNotFoundException {
Class test = Class.forName("Test1");//创建类
if (test.isAnnotationPresent(Id.class)){//判断类上是否有Id注解
boolean flag = false;
Field[] fields = test.getDeclaredFields();//获取类的所有属性
for(Field field:fields){
if (field.getName().equals("id")&&field.getType().getSimpleName().equals("int")){//判断是否是int类型的id
flag = true;
break;
}
}
if (flag == false){
throw new NotId(test.getName()+"被Id注解,必须有int类型的id属性");
}
}
}
}
class NotId extends RuntimeException{//自定义异常,忘记回去复习
public NotId() {
}
public NotId(String message) {
super(message);
}
}



