理解Java中的注释
我试图通过一些在线资料来学习java中的注释。
在下面的代码中,我在这行传递的亲爱的“Hello world”字符串发生了什么: @Test_Target(doTestTarget="Hello World !")
?
@Target(ElementType.METHOD) public @interface Test_Target { public String doTestTarget(); }
以上是定义的注释,下面是它的用法
public class TestAnnotations { @Test_Target(doTestTarget="Hello World !") private String str; public static void main(String arg[]) { new TestAnnotations().doTestTarget(); } public void doTestTarget() { System.out.printf("Testing Target annotation"); } }
当我运行此代码时,它只打印Testing Target annotation
请帮帮我,我是注释的新手。
注释基本上是可以附加到字段,方法,类等的数据位。
在Java中声明注释的语法有点尴尬。 它们看起来有点像接口(毕竟它们是用@interface
声明的),但它们并不是真正的接口。 我想你可能已经在你的TestAnnotations
类中放了doTestTarget()
方法,因为你认为你的注释是一个接口而你需要实现它。 事实并非如此 – 如果您愿意,可以删除此方法并从代码中调用它,这样做不会给您带来任何问题。
此外,您可能没有打算将注释放在字段str
。 注释仅适用于紧随其后的内容。 因此,您的代码无法编译,因为您已将注释应用于字段,但声明您的注释只能应用于方法。 将@Target(ElementType.METHOD)
更改为@Target(ElementType.FIELD)
,然后应编译代码。
至于字符串Hello World !
会发生什么Hello World !
,它被写入.class文件,可用于读取Java类的任何工具。 但是,它不一定在运行时在JVM中可用。 发生这种情况是因为您没有为@Test_Target
注释指定@Test_Target
。 @Retention
的默认值是RetentionPolicy.CLASS
,这意味着JVM可能无需将它们加载到类文件中。 (有关RetentionPolicy枚举,请参阅Javadoc 。)
我想你想看到一些在运行时从这个注释中读取值的方法。 如果是这样,我建议将@Retention(RetentionPolicy.RUNTIME)
添加到注释中,以确保它在运行时可用。
要在运行时访问注释及其中包含的值,您需要使用reflection。 我按如下方式重写了你的TestAnnotations
类,以便快速演示:
import java.lang.reflect.Field; public class TestAnnotations { @Test_Target(doTestTarget="Hello World !") private String str; public static void main(String[] args) throws Exception { // We need to use getDeclaredField here since the field is private. Field field = TestAnnotations.class.getDeclaredField("str"); Test_Target ann = field.getAnnotation(Test_Target.class); if (ann != null) { System.out.println(ann.doTestTarget()); } } }
当我运行此代码时,它给我以下输出:
你好,世界 !
原则上,添加注释本身并不会从根本上改变程序行为。
在您的情况下,您创建了一个新的注释类型@Test_Target
,它可以用于任何方法(由其@Target
注释指示)。
然后你应用它不是一个方法,而是应用于str
字段(我认为应该给编译器错误)。
与此doTestTarget
,您正在使用doTestTarget
方法创建一个对象,并调用它,并获得预期的结果(即执行该方法)。
如果你希望你的注释做的不仅仅是在那里并为源的读者提供一些信息,你必须使用它 – 在编译时使用注释处理器,或者在运行时使用reflection(那么你需要还有@Retention(RUNTIME)
作为Test_Target
的注释。)
本着学习的精神,另一种方法是使用带注释的类而不以方法或字段为目标。 首先使用您需要的方法和Retention Policy to Runtime声明您的接口
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) public @interface Test_Target { public String doTestTarget() default "default string"; }
然后注释为您的类创建的接口。 从您的类中找到带注释的类,然后使用它调用该方法。
import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; @Test_Target(doTestTarget="Hello World !") public class TestAnnotations { public static void main(String[] args) throws Exception { AnnotatedElement c = TestAnnotations.class; if(c.isAnnotationPresent(Test_Target.class)) { Annotation singleAnnotation = c.getAnnotation(Test_Target.class); Test_Target tt = (Test_Target) singleAnnotation; System.out.println(tt.doTestTarget()); } }
}
结果是:Hello World!