2016-01-01 57 views
16

我在看一個相當瑣碎類定義了一個註解接收器類型一個方法:如何訪問類型註解接收器類型的參數

class Foo<T> { 
    void foo(Foo<@Bar T> this) {} 
} 

我現在想訪問類型標註在接收器類型的參數@Bar但訪問時,接收器Java反射API返回的註釋原始類型:

assert Foo.class.getDeclaredMethod("foo") 
       .getAnnotatedReceiverType() 
    instanceof AnnotatedParameterizedType; 

斷言失敗爲返回的註釋類型是returne d作爲原始類型Foo。這是故意的嗎?在訪問返回的AnnotatedType的實現的私有屬性時,我仍然可以找到@Bar註釋。

我運行最新的Java 8

+0

你可以看到一個例子[這裏](HTTPS:/ /gist.github.com/psamsotha/a68b9dafb457b3168ed7)關於如何獲得'AnnotatedParameterizedType',但我不太確定從那裏你將如何得到註釋。這聽起來像你在說你正在訪問底層實現的私有領域。出於好奇,你能證明你會怎麼做? –

+0

我應該嘗試過。我立刻想到這是由於返回錯誤的類型表示造成的,但正如現在接受的答案所述,這顯然是一個錯誤。 –

回答

0

原來這是一個簡單的錯誤。我首先想到的是,這是對相關問題的暗示,但類型註釋與此無關。類型註釋在Java運行時的當前實現中測試得很差。我發現的問題數量之多,在深潛此事:

-1

的版本。如果我運行此:

Foo<Integer> f = new Foo<>(); 
Method m = f.getClass().getDeclaredMethod("foo"); 
AnnotatedType at = m.getAnnotatedReceiverType(); 
for (Annotation a:at.getAnnotations()) { 
    System.out.println("Annotation: "+a); 
} 

然後我把註釋上的接收器類型是這樣的:

public void foo(@Bar(1) Foo<T> this) {} 

現在您可以訪問@Bar(1)註釋。請注意,我將註釋直接放在ReceiverParameter上,而不是它的類型參數。

我知道這只是現在的一部分答案......但我想從某個地方開始。其他人可能會添加並提供一個完整的答案,或者隨着時間的推移我會學到更多一些...... Receiver Types和註解的這種使用對我而言都是非常新的,沒有太多的文檔和樣本可供借鑑。

我懷疑是沒有辦法訪問這些信息。也the answer an another topic參見:

對於註釋,約從方法參數類型參數得到註解,也沒有給出上述方式。

同一主題將告訴您如何訪問字段中類型參數的註釋。

+0

我已經可以訪問類型本身的註釋,但不能註釋註釋類型的參數。你提出的建議也適用於原始類型。一個'Class'實例永遠不會代表一個泛型類型,你總是需要通過其中一個來調用'getDeclaredMethod'。 –

+0

是的,我發現它在原始類型上工作,並且必須修改我的答案,因爲我原來說這是問題的一部分,但事實並非如此。這真是令人困惑和複雜,我懷疑我只是沒有看到它應該如何使用。我認爲這非常有趣,也沒有真正回答。 – YoYo

7

這是一個已知的bug JDK-8058220。但是,問題看起來可能更深。

如果不更改類文件格式和相應的規範更新,就不能輕易修復它。目前,類文件不包含區分接收器參數和常規接收器參數所需的信息(請參閱JDK-8062582)。

+0

這是非常有趣的,並顯示有合成/強制參數的問題。但是我沒有看到這與原來的問題有什麼關係。通過示例代碼,我完全能夠訪問接收器參數上的類型註釋。這個問題 - 我理解的方式 - 就是我們應該如何訪問放入接收器參數類型的類型參數中的註釋。 'foo(Foo <@Bar T> this)'vs'foo(@Boo Foo this)'。 – YoYo