2016-02-02 34 views
3

以下是在JLS https://docs.oracle.com/javase/specs/jls/se7/html/jls-18.htmlJava語法:NonWildcardTypeArguments

NonWildcardTypeArguments: 
    <TypeList> 

TypeList: 
    ReferenceType { , ReferenceType } 

ReferenceType: 
    Identifier [TypeArguments] { . Identifier [TypeArguments] } 

TypeArguments: 
    < TypeArgument { , TypeArgument } > 

TypeArgument: 
    ReferenceType 
    ? [ (extends | super) ReferenceType ] 

根據NonWildcardTypeArguments的名稱第18章的規定,它不應該允許外卡。但是,下面的代碼編譯

public class NonWildcardTypeArgumentsTest { 
    public void test(Test<java.util.Set<? extends Object>> args) { 

    } 
} 

class Test<T> {} 

本例中的類型參數滿足NonWildcardTypeArguments的定義,它包含通配符:

<java.util.Set<? extends Object>> 

我爲此感到困惑。爲什麼它有效?謝謝

+0

作爲一個方面說明,這不是JLS8 – assylias

+1

這是jls7的第18章。 – CMZS

+2

是的,我剛剛提到它已被刪除在JLS 8中。 – assylias

回答

1

通配符是Set的類型參數,而不是Test。這裏的語法是一個樹狀結構,其中每個類型參數適用於其外部的類型。

Test<T> 
    ↓ 
    Set<E> 
     ↓ 
    ? extends Object 

NonWildcardTypeArguments只要求每個類型參數是一個ReferenceType,其Set<? extends Object>滿足,因爲它的形式Identifier<TypeArgument>的。 (? extends ObjectTypeArgument,但不是一個ReferenceType。)

例如,​​是NonWildcardTypeArguments<? extends Set<Object>>不是。

所以是的,在類型參數中有一個通配符「in」,但它嵌套在樹中的一個級別。 NonWildcardTypeArguments構造只關心它內部的參數。

無論如何,正如assylias指出的,這個語法結構似乎不再存在了,但我認爲解釋仍然很有趣。 (我試過搜索JLS 8 PDF爲「NonWildcardTypeArguments」,並沒有拿出任何東西。)

+0

我已經閱讀了JLS8的第19章(語法)。它甚至讓我更加困惑。例如,這裏定義的六個名稱構造對我來說似乎是一樣的。畢竟,我需要的是從解析器的角度理解java語法。因此,他們如何命名這些結構並不重要。感謝您發佈帖子。謝謝你的好解釋。 – CMZS

+0

所有的語法結構都是上下文使用的。如果你想了解它們,你可能會通過查看定義來從錯誤的方向看待它們。你必須瞭解他們如何習慣瞭解他們爲什麼以他們的方式存在。 6.5.1例如描述名稱被鋪設的過程。此外,與類型參數相同,請注意名稱構造是樹結構。 (Javac將字面意義上的數據結構表示爲樹。) – Radiodef