Java注释提供有关代码的信息,并且它们对所注释的代码没有直接影响。 在本教程中,我们将学习Java注释,如何编写自定义注释 ,注释用法以及如何使用反射来解析注释 。
注释是在Java 1.5中引入的,现在它已在Hibernate, Jersey和Spring等Java框架中大量使用。 注释是有关嵌入在程序本身中的程序的元数据。 可以通过注释解析工具或编译器进行解析。 我们还可以指定注释可用性以仅编译时间或也可以直到运行时。
在注释之前,可以通过java注释或javadoc获得程序元数据,但是注释提供的功能更多。 它不仅包含元数据,而且还可以将其提供给运行时使用,并且注释解析器可以使用它来确定流程。 例如,在Jersey网络服务中,我们将带有URI字符串的PATH注释添加到方法中,并且在运行时jersey对其进行解析,以确定要为给定URI模式调用的方法。
在Java中创建自定义注释
创建自定义注释与编写接口相似,不同之处在于它的接口关键字以@符号为前缀。 我们可以在注解中声明方法。 让我们看一下注释示例,然后我们将讨论其功能。
package com.journaldev.annotations;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{String author() default 'Pankaj';String date();int revision() default 1;String comments();
}
- 注释方法不能有参数。
- 注释方法的返回类型仅限于原语,字符串,枚举,注释或它们的数组。
- 注释方法可以具有默认值。
- 批注可以附加元批注。 元注释用于提供有关注释的信息。 元注释有四种类型:
- @Documented –指示使用此注释的元素应由javadoc和类似工具记录。 此类型应用于注释其注释会影响其客户端对已注释元素的使用的类型的声明。 如果类型声明用Documented进行注释,则其注释将成为带注释元素的公共API的一部分。
- @Target –指示注释类型适用的程序元素的种类。 一些可能的值是TYPE,METHOD,CONSTRUCTOR,FIELD等。如果没有Target元注释,则可以在任何程序元素上使用注释。
- @Inherited –表示注释类型是自动继承的。 如果用户在类声明中查询注释类型,并且该类声明中没有该类型的注释,则将自动查询该类的超类以获取注释类型。 重复此过程,直到找到该类型的注释,或到达类层次结构(对象)的顶部为止。
- @Retention –指示带注释类型的注释将保留多长时间。 它采用RetentionPolicy参数,其可能值为SOURCE,CLASS和RUNTIME
Java内置注释
Java提供了三个内置注释。
- @Override –当我们要重写超类的方法时,应使用此批注通知编译器我们正在重写方法。 因此,当删除或更改超类方法时,编译器将显示错误消息。
- @Deprecated –当我们希望编译器知道某个方法已被弃用时,应使用此注释。 Java建议在javadoc中,我们应提供有关为什么不赞成使用此方法以及可以使用什么替代方法的信息。
- @SuppressWarnings –这只是告诉编译器忽略它们产生的特定警告,例如在泛型中使用原始类型。 它的保留策略是SOURCE,并且被编译器丢弃。
让我们看一个Java示例,它显示内置注释的用法以及在上面的示例中由我们创建的自定义注释的用法。
package com.journaldev.annotations;import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;public class AnnotationExample {public static void main(String[] args) {}@Override@MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 1)public String toString() {return 'Overriden toString method';}@Deprecated@MethodInfo(comments = 'deprecated method', date = 'Nov 17 2012')public static void oldMethod() {System.out.println('old method, don't use it.');}@SuppressWarnings({ 'unchecked', 'deprecation' })@MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 10)public static void genericsTest() throws FileNotFoundException {List l = new ArrayList();l.add('abc');oldMethod();}}
我相信示例是自我解释,并显示了在不同情况下使用注释的情况。
Java注解解析
我们将使用Reflection来解析类中的Java批注。 请注意,注释保留策略应为RUNTIME,否则其信息将在运行时不可用,我们将无法从中获取任何数据。
package com.journaldev.annotations;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;public class AnnotationParsing {public static void main(String[] args) {try {for (Method method : AnnotationParsing.class.getClassLoader().loadClass(('com.journaldev.annotations.AnnotationExample')).getMethods()) {// checks if MethodInfo annotation is present for the methodif (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {try {// iterates all the annotations available in the methodfor (Annotation anno : method.getDeclaredAnnotations()) {System.out.println('Annotation in Method ''+ method + '' : ' + anno);}MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);if (methodAnno.revision() == 1) {System.out.println('Method with revision no 1 = '+ method);}} catch (Throwable ex) {ex.printStackTrace();}}}} catch (SecurityException | ClassNotFoundException e) {e.printStackTrace();}}}
上面程序的输出是:
Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)
Java注释教程就这些了,我希望您从中学到了一些东西。
参考: 带有自定义注释示例的Java注释教程,以及来自JCG合作伙伴 Pankaj Kumar的《 使用反射进行解析》 ,位于Developer Recipes博客上。
翻译自: https://www.javacodegeeks.com/2012/11/java-annotations-tutorial-with-custom-annotation.html