L'annotation (annotation) est une interface Le programme peut obtenir l'objet Annotation de l'élément de programme spécifié via. réflexion. Obtenez ensuite les métadonnées dans l'annotation via l'objet Annotation.
Selon l'utilisation et le but des annotations, nous pouvons diviser les annotations en trois catégories : les annotations système, les méta-annotations et les annotations personnalisées.
Les annotations système sont les annotations intégrées du JDK, comprenant principalement : @Override, @Deprecated, @SuppressWarnings.
Lors de la modification d'une méthode, cela signifie que la méthode remplace la méthode de la classe parent, ou la méthode qui implémente l'interface
interface Demo{ public void print(); }public class Test implements Demo{ @Override public void print() { } }
Modifier les méthodes obsolètes
Supprimer les avertissements du compilateur, c'est-à-dire supprimer les avertissements.
Les valeurs des paramètres courants sont :
名称 | 作用 |
---|---|
rawtypes | 表示传参时也要传递带泛型的参数 |
deprecation | 使用了不赞成使用的类或方法时的警告 |
unchecked | 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型 |
fallthrough | 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告; |
path | 在类路径、源文件路径等中有不存在的路径时的警告; |
serial | 当在可序列化的类上缺少 serialVersionUID 定义时的警告; |
finally | 任何 finally 子句不能正常完成时的警告; |
all | 关于以上所有情况的警告。 |
Les exemples sont les suivants :
// 抑制单类型@SuppressWarnings("unchecked")public void print() { @SuppressWarnings("rawtypes") List list = new ArrayList(); list.add("a"); }// 抑制多类型@SuppressWarnings({ "unchecked", "rawtypes" })public void print() { List list = new ArrayList(); list.add("a"); }// 抑制所有类型@SuppressWarnings({ "all" })public void print() { List list = new ArrayList(); list.add("a"); }
Le rôle des méta-annotations est d'annoter d'autres annotations. Java5.0 définit 4 types méta-annotation standards, qui sont utilisés pour fournir des descriptions d'autres types d'annotations.
Les méta-annotations définies sont les suivantes : @Target, @Retention, @Documented, @Inherited.
@Target définit la portée des objets modifiés par Annotation La portée de modification spécifique est la suivante :
public enum ElementType { // 用于描述类、接口(包括注解类型) 或enum声明 TYPE, // 用于描述域(即变量) FIELD, // 用于描述方法 METHOD, // 用于描述参数 PARAMETER, // 用于描述构造器 CONSTRUCTOR, // 用于描述局部变量 LOCAL_VARIABLE, // 用于描述注解类型 ANNOTATION_TYPE, // 用于描述包 PACKAGE }
@Rétention définit la durée pendant laquelle l'annotation est conservée, c'est-à-dire qu'elle indique le cycle de vie de l'annotation.
public enum RetentionPolicy { // 在源文件中有效(编译器要丢弃的注解) SOURCE, // class 文件中有效(默认,编译器将把注解记录在类文件中,但在运行时 VM 不需要保留注解) CLASS, // 在运行时有效(编译器将把注解记录在类文件中,在运行时 VM 将保留注解,因此可以反射性地读取) RUNTIME }
@Documented définit l'annotation, indiquant qu'un certain type d'annotation sera documenté via javadoc et des outils par défaut similaires.
Si une déclaration de type est annotée avec Documented, son annotation fera partie de l'API publique de l'élément annoté.
@Inherited définit l'annotation, indiquant que le type d'annotation est automatiquement hérité, c'est-à-dire qu'un type d'annotation modifié avec @Inherited est utilisé une classe, alors cette annotation sera utilisée pour les sous-classes de cette classe.
Si vous utilisez un type d'annotation pour annoter autre chose que la classe, @Inherited ne sera pas valide.
Cette méta-annotation facilite uniquement l'héritage des annotations de la classe parent ; les annotations sur les interfaces implémentées ne sont pas valides.
Lorsque la Rétention de l'annotation annotée avec le type d'annotation @Inherited est RetentionPolicy.RUNTIME, l'API de réflexion améliore cet héritage. Si nous utilisons java.lang.reflect pour interroger l'annotation d'un type d'annotation @Inherited, l'inspection réfléchissante du code commencera à fonctionner : vérifiez la classe et sa classe parent jusqu'à ce que le type d'annotation spécifié soit trouvé, ou le niveau supérieur de la structure d'héritage de classe. est atteint
Les exemples sont les suivants :
// 定义注解@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Inherited@interface MyAnotation{ public String name(); }// 作用在类上@MyAnotation(name="parent") class Parent{ }// 继承 Parent 类public class Test extends Parent{ public static void main(String[] args) { Class<?> cls = Test.class; // 通过 @Inherited 继承父类的注解 Annotation annotation = cls.getAnnotation(MyAnotation.class); MyAnotation myAnotation = (MyAnotation) annotation; System.out.println(myAnotation.name()); } }// 输出结果:parent(若注释掉注解,返回异常)
// 定义注解@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@interface MyAnnotation { public String name(); public String age(); }// 调用注解@MyAnnotation(name="cook",age="100")public class Test { public static void main(String[] args) { Class<?> cls = Test.class; // 1.取得所有注解 Annotation[] annotations =cls.getAnnotations(); // 2.取得指定注解 MyAnnotation annotation = (MyAnnotation)cls.getAnnotation(MyAnnotation.class); } }
// 定义注解@Retention(RetentionPolicy.RUNTIME) // 修改作用范围@Target(ElementType.METHOD)@interface MyAnnotation { public String name(); public String age(); } // 调用注解public class Test { public static void main(String[] args) throws Exception { Class cls = Test.class; Method method = cls.getDeclaredMethod("print", null); // 1.取得所有注解 Annotation[] annotations = method.getDeclaredAnnotations(); // 2.取得指定注解 MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class); }
// 定义注解@Retention(RetentionPolicy.RUNTIME) // 修改作用范围@Target(ElementType.PARAMETER)@interface MyAnnotation { public String name(); public String age(); }public class Test { public static void main(String[] args) throws Exception { Class cls = Test.class; Method method = cls.getDeclaredMethod("print", new Class[]{String.class,String.class}); getAllAnnotations(method); } // 作用在参数上 public void print(@MyAnnotation(name = "cook", age = "100") String name, String age) { } public static void getAllAnnotations(Method method) { Annotation[][] parameterAnnotions = method.getParameterAnnotations(); // 通过反射只能取得所有参数类型,不能取得指定参数 Class[] paraemterTypes = method.getParameterTypes(); int i = 0; for (Annotation[] annotations : parameterAnnotions) { Class paraemterType = paraemterTypes[i++]; for (Annotation annotation : annotations) { if (annotation instanceof MyAnnotation) { MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println(paraemterType.getName()); System.out.println(myAnnotation.name()); System.out.println(myAnnotation.age()); } } } } }
// 定义注解@Retention(RetentionPolicy.RUNTIME) // 修改作用范围@Target(ElementType.FIELD)@interface MyAnnotation { public String name(); public String age(); }public class Test { // 作用在变量上 @MyAnnotation(name = "cook", age = "100") private String name; public static void main(String[] args) throws Exception { Class cls = Test.class; Field field = cls.getDeclaredField("name"); Annotation[] fieldAnnotions = field.getDeclaredAnnotations(); MyAnnotation annotation = (MyAnnotation) field.getAnnotation(MyAnnotation.class); } }