我正在用Java语言规范(第三版)阅读Java的泛型。在"4.6擦除“一节中定义了类型擦除。关于类型变量的擦除,它说
类型变量(§4.4)的擦除是其最左界的擦除。
这使我对类型变量和类型参数之间的区别有点困惑,因为"4.4类型变量“部分有定义:TypeParameter: TypeVariable TypeBound,其中绑定是可选的。但是,也许您可以用它所显示的类型参数来标识类型变量,因为类型变量只能(?)出现在一个“上下文”中,然后将类型变量的最左界定义为其相应类型参数或Object的最左界,以防类型参数中没有显式绑定?
发布于 2011-08-16 08:28:00
如果没有给出类型变量的绑定,则假定对象。
在你的链接里找到的。这意味着,给定FirstClass<T extends String>和SecondClass<V>,您可以得到:
FirstClass类型参数:T extends String。类型变量:T。类型绑定:String。SecondClass类型参数:V类型变量:V。类型绑定:默认为Object。编辑:通过类型参数,类型变量和类型绑定I不是指语法规则,而是指概念。因此,extends只是关键字。
关于最左边的范围,您可以在同一个链接中找到答案,在第一个引用之后有两个句子:
绑定中类型的顺序很重要,因为类型变量的擦除是由其绑定中的第一个类型决定的,并且类类型或类型变量只能出现在第一个位置。
发布于 2017-05-02 17:00:23
TL博士-上下文就是一切!
非正式地,“类型变量”和“类型参数”互为同义词[https://docs.oracle.com/javase/tutorial/extra/generics/methods.html]。
然而,在形式上,https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.2明确地将它们描述为两个不同但密切相关的抽象。
在过去,我自己也有过类似的问题,在很多关于泛型的文献中,“类型参数”和“类型变量”的用法不够清晰。
根据我对https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.2的解释,TypeParameter是出现在参数化类‘或方法的类型参数部分(声明的<>部分)中的内容。
……“。我的理解是,为了使用TypeVariable,您必须首先按照为声明TypeParameter而指定的规则填写方法的类型参数部分或类的类型参数部分。
TypeParameter:
{TypeParameterModifier} Identifier [TypeBound]
TypeParameterModifier:
Annotation
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
AdditionalBound:
& InterfaceType读和..。
TypeVariable:
{Annotation} Identifier ...I将这两个结果解释为如果在一个上下文中使用标识符T,而T在上下文中有或可以在其后面有一个TypeBound,那么T就是TypeParameter。或者,如果标识符T是在不允许TypeBound__s的上下文中使用的,那么T就是TypeVariable。
我认为TypeParameter类似于方法声明的形式参数。
当“时,我将其解释为在类型参数部分声明一个TypeParameter也类似于声明一个类,该类随后可以用作实例变量的引用类型--在某种意义上。
我的意思是,为了使以下内容合法.
class Foo {
private Bar bar;
}
class Boff extends Foo { }..then --您必须首先引入-- 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<>(); ...the Boff在<>菱形中,既不是类型变量,也不是类型参数。它是一个类型参数。
https://stackoverflow.com/questions/7075363
复制相似问题