2011-04-16 78 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!