2011-08-16 107 views
4

我正在閱讀Java中的泛型,使用Java語言規範,第三版。在「4.6 Erasure」部分定義了類型擦除。在擦除類型變量時,它表示類型變量的定義和參數

擦除類型變量(§4.4)是擦除其最左邊界。

這混淆了我關於自節「4.4 Type Variables」有定義類型變量類型參數區分一下:TypeParameter: TypeVariable TypeBound其中綁定是可選的。但是也許你可以用它出現的類型參數來標識一個類型變量,因爲一個類型變量只能出現在一個「上下文」中,然後一個類型變量的最左邊界被定義爲其相應類型參數的最左邊界或者Object如果在類型參數中沒有明確的限制出現?

回答

5

如果沒有給定類型變量的限制,則假定爲對象。

找到您的鏈接。這意味着,給定FirstClass<T extends String>SecondClass<V>你會得到:

  1. 類:FirstClass類型參數:T extends String。類型變量:T。類型綁定:String
  2. 類:SecondClass類型參數:V類型變量:V。類型綁定:默認爲Object

編輯:通過類型參數類型綁定可變和型我說的不是語法規則,但這個概念。因此,extends只是關鍵字。

關於最左邊的束縛,你可以找到在同一條鏈路的答案,第一次報價後兩句:

的類型綁定的順序是僅在顯著類型變量的擦除由其邊界中的第一個類型確定,並且類類型或類型變量可能只出現在第一個位置。

+0

你的例子沒有解釋如果在擦除類型變量的定義中,「最左邊界」正式對應於類型變量出現在類型參數中的最左邊界。你的示例的擦除不會是刪除'FirstClass'和刪除'SecondClass',並假設這些只是類名,擦除將等於名稱?類型變量的存在與語法中的類型邊界無關,但類型邊界顯示爲類型參數的可選部分。嚴格地說,'extends'是類型綁定的一部分。 – user847614

+0

是的,如果我寫了__TypeBound__語法規則。在前面的引用之後有兩個句子可以讀取:「綁定中的類型順序僅僅是重要的,因爲類型變量的刪除是由其邊界中的第一個類型確定的,並且類類型或類型變量可能僅限於出現在第一位。「我將編輯包含它的答案。 – Serabe

0

TL; DR - 背景決定一切!


非正式地, 「類型變量」 和 「類型參數」 可互換使用,作爲彼此的同義詞[even by Gilad Bracha — the creator of Java's Generics implementation]。

然而,形式上,the JLS明確描述爲兩個不同的 - 但密切相關的 - 抽象。

在過去,我有過類似的問題,我自己有關的術語「類型參數」,並在大量仿製藥的文獻「類型變量」的低於水晶般清晰的使用。

從我的the more-recent Java 8 JLS解釋,一個TypeParameter就是出現在參數化類的或方法的類型參數部分[聲明<>部分。

The JLS says, "A type variable is introduced by the declaration of a type parameter..."。我理解這意味着,爲了使用TypeVariable,必須先填寫方法的[或者類]按照宣告一個TypeParameter ...

指定的規則類型參數節
TypeParameter: 
    {TypeParameterModifier} Identifier [TypeBound] 

TypeParameterModifier: 
    Annotation 

TypeBound: 
    extends TypeVariable 
    extends ClassOrInterfaceType {AdditionalBound} 

AdditionalBound: 
    & InterfaceType 

閱讀the above syntactic production for TypeParameterthis one for TypeVariable ...

TypeVariable: 
    {Annotation} Identifier 

...我解釋這兩個作品的意思是,如果一個標識符T是在上下文中,其中T具有[或可以具有]一個TypeBound後,所用然後TTypeParameter。可選地,如果一個標識符T在使用上下文,其中TypeBound小號是不允許的,那麼TTypeVariable


我想的TypeParameter爲類似於一個形式參數的方法聲明

the JLS says, "A type variable is an unqualified identifier used as a type in class, interface, method, and constructor bodies",解讀該意味着聲明中的類型參數截面的TypeParameter,是有點類似於聲明隨後可以用作,比如,一個實例變量的引用類型的類也 - 某種意義上的

我的意思是,爲了下面是合法的......

class Foo { 

    private Bar bar; 
} 

class Boff extends Foo { } 

..那麼你必須首先引入Bar類型的聲明之前,它可以用在Foo的身體。類似地,類型參數<T extends Foo>必須先以宣佈以下是合法的......

class Baz<T extends Foo> { /* The TypeParameter that "introduces" T comes first */ 

    private T quux; /* now T is a TypeVariable in this context */ 

    /* <U extends Number> is the TypeParameter that "introduces" the TypeVariable, U */ 

    public <U extends Number> List<? super U> m(Class<U> clazz) throws Exception { /* <U extends Number> is the TypeParameter */ 

     U u = clazz.newInstance(); /* U is a TypeVariable in this context */ 

     /*...*/ 

     List<? super U> list = new LinkedList<>(); /* U is a TypeVariable in this context; just like it is in this method's return type */   

     /*...*/ 

     list.add(u); 

     /*...*/ 

     return list; 

    } 

} 

如果我允許更加具體......

Baz<Boff> buzz = new Baz<>(); 

...的Boff<>鑽石裏面,既不是變量也不是參數。這是一個類型論據