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 TypeParameter
和this one for TypeVariable
...
TypeVariable:
{Annotation} Identifier
...我解釋這兩個作品的意思是,如果一個標識符T
是在上下文中,其中T
具有[或可以具有]一個TypeBound
後,所用然後T
是TypeParameter
。可選地,如果一個標識符T
在使用上下文,其中TypeBound
小號是不允許的,那麼T
是TypeVariable
。
我想的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
的<>
鑽石裏面,既不是型變量也不是型參數。這是一個類型論據。
你的例子沒有解釋如果在擦除類型變量的定義中,「最左邊界」正式對應於類型變量出現在類型參數中的最左邊界。你的示例的擦除不會是刪除'FirstClass'和刪除'SecondClass',並假設這些只是類名,擦除將等於名稱?類型變量的存在與語法中的類型邊界無關,但類型邊界顯示爲類型參數的可選部分。嚴格地說,'extends'是類型綁定的一部分。 – user847614
是的,如果我寫了__TypeBound__語法規則。在前面的引用之後有兩個句子可以讀取:「綁定中的類型順序僅僅是重要的,因爲類型變量的刪除是由其邊界中的第一個類型確定的,並且類類型或類型變量可能僅限於出現在第一位。「我將編輯包含它的答案。 – Serabe