- 注解,也叫注释,英文: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); } }