2011-04-16 76 views
10

我正在尝试通过一些在线材料来学习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

请帮我,我完全新的诠释。

+0

你会期望*代码做什么? – 2011-04-16 10:11:47

+0

对不起迈克尔..但是,因为我对这个主题是全新的......你可以请让我知道为什么当我们不期望控制台显示它时我们通过了这个字符串 – 2011-04-16 10:13:19

+0

你在阅读哪些在线材料? – 2011-04-16 10:13:51

回答

20

注解基本上数据的比特可以附加到字段,方法,类等等

的语法在Java注释声明是一个有点尴尬。它们看起来有点像接口(它们毕竟是用@interface声明的),但它们并不是真正的接口。我想你可能已经把doTestTarget()方法放在你的TestAnnotations类中,因为你认为你的注解是一个接口,并且你需要实现它。这不是真的 - 如果你愿意,你可以从你的代码中删除这个方法和对它的调用,这样不会给你带来任何问题。

此外,您可能没有打算在字段str上添加注释。注释仅适用于紧随其后的内容。因此,您的代码无法编译,因为您已将注释应用于字段,但声明您的注释只能应用于方法。将@Target(ElementType.METHOD)更改为@Target(ElementType.FIELD),然后编译代码。

至于字符串Hello World !发生了什么,它会被写入.class文件,并可用于任何读取Java类的工具。但是,它在运行时不一定在JVM中可用。发生这种情况是因为您没有为您的@Test_Target注释指定@Retention@Retention的默认值是RetentionPolicy.CLASS,这意味着JVM可能不会费心将它们加载到类文件之外。 (请参阅Javadoc for the RetentionPolicy enum。)

我想你想看到某种方式在运行时读取此注释的值。如果是这样,我建议将@Retention(RetentionPolicy.RUNTIME)添加到您的注释中,以确保它在运行时可用。

要在运行时访问注释和其中包含的值,您需要使用反射。我已经重写你的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()); 
     } 
    } 
} 

当我运行这段代码,它给了我下面的输出:

 
Hello World ! 
+0

java注释提供了有关代码的信息,供编译器使用。通过http://www.journaldev.com/721/java-annotations-tutorial-with-custom-annotation-example-and-parsing-using-reflection了解更多信息。 – Pankaj 2012-12-09 07:20:14

4

原则上,自行添加注释不会从根本上改变程序的行为。

对于您的情况,您创建了一个新的注释类型@Test_Target,可以通过任何方法使用(如其注释@Target所示)。

然后,你不是应用这个方法,而是应用到str字段(这应该会导致编译器错误,我认为)。

与此无关,您正在使用doTestTarget方法创建一个对象,并调用它并获得预期结果(即执行该方法)。

如果您希望您的注释做的不仅仅是在那里并为源代码的读者提供一些信息,您必须在编译时使用注释处理器或在运行时使用反射那么你就还需要@Retention(RUNTIME)作为Test_Target注解。)

1

在学习的精神,另辟蹊径是使用带注释的类而不用定位方法或字段。 首先声明你的界面与您需要的方法和保留策略运行时

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!