首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型变量和参数的定义

类型变量和参数的定义
EN

Stack Overflow用户
提问于 2011-08-16 08:17:52
回答 2查看 2.1K关注 0票数 6

我正在用Java语言规范(第三版)阅读Java的泛型。在"4.6擦除“一节中定义了类型擦除。关于类型变量的擦除,它说

类型变量(§4.4)的擦除是其最左界的擦除。

这使我对类型变量和类型参数之间的区别有点困惑,因为"4.4类型变量“部分有定义:TypeParameter: TypeVariable TypeBound,其中绑定是可选的。但是,也许您可以用它所显示的类型参数来标识类型变量,因为类型变量只能(?)出现在一个“上下文”中,然后将类型变量的最左界定义为其相应类型参数或Object的最左界,以防类型参数中没有显式绑定?

EN

回答 2

Stack Overflow用户

发布于 2011-08-16 08:28:00

如果没有给出类型变量的绑定,则假定对象。

在你的链接里找到的。这意味着,给定FirstClass<T extends String>SecondClass<V>,您可以得到:

  1. 类:FirstClass类型参数:T extends String。类型变量:T。类型绑定:String
  2. 类:SecondClass类型参数:V类型变量:V。类型绑定:默认为Object

编辑:通过类型参数类型变量类型绑定I不是指语法规则,而是指概念。因此,extends只是关键字。

关于最左边的范围,您可以在同一个链接中找到答案,在第一个引用之后有两个句子:

绑定中类型的顺序很重要,因为类型变量的擦除是由其绑定中的第一个类型决定的,并且类类型或类型变量只能出现在第一个位置。

票数 6
EN

Stack Overflow用户

发布于 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而指定的规则填写方法的类型参数部分或类的类型参数部分。

代码语言:javascript
复制
TypeParameter:
    {TypeParameterModifier} Identifier [TypeBound]

TypeParameterModifier:
    Annotation

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType {AdditionalBound}

AdditionalBound:
    & InterfaceType

读和..。

代码语言:javascript
复制
TypeVariable:
    {Annotation} Identifier 

...I将这两个结果解释为如果在一个上下文中使用标识符T,而T在上下文中有或可以在其后面有一个TypeBound,那么T就是TypeParameter。或者,如果标识符T是在不允许TypeBound__s的上下文中使用的,那么T就是TypeVariable

我认为TypeParameter类似于方法声明的形式参数

时,我将其解释为在类型参数部分声明一个TypeParameter也类似于声明一个类,该类随后可以用作实例变量的引用类型--在某种意义上。

我的意思是,为了使以下内容合法.

代码语言:javascript
复制
class Foo { 

   private Bar bar;
}

class Boff extends Foo { }

..then --您必须首先引入-- Bar类型的声明,然后才能在Foo的主体中使用它。类似地,类型参数<T extends Foo>必须首先声明,才能使以下内容成为合法的.

代码语言:javascript
复制
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;

    }

} 

如果允许我说得更具体..。

代码语言:javascript
复制
Baz<Boff> buzz = new Baz<>(); 

...the Boff<>菱形中,既不是类型变量,也不是类型参数。它是一个类型参数

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7075363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档