加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java 7钻石操作符和派生类的初始化

发布时间:2020-12-14 05:46:52 所属栏目:Java 来源:网络整理
导读:class A {}class B extends A {}class HolderT { T object; Holder(T object) { this.object = object; }} 有一个Holder类来保存一些使用泛型创建的对象. 在main()中,当使用菱形运算符初始化时,它不会编译(Java 7),派生类传递给Holder的构造函数(需要A /找到
class A {}

class B extends A {}

class Holder<T> {

    T object;

    Holder(T object) {
        this.object = object;
    }
}

有一个Holder类来保存一些使用泛型创建的对象.
在main()中,当使用菱形运算符初始化时,它不会编译(Java 7),派生类传递给Holder的构造函数(需要A /找到B):

public static void main(String[] args) {    
    Holder<A> holder = new Holder<>(new B());        
}

但是,如果在右侧部分指定了基本类型,它将编译并运行:

public static void main(String[] args) {
    Holder<A> holder = new Holder<A>(new B());
}

为什么?钻石运算符是否使用与左侧相同的类型参数定义赋值的右侧部分?

解决方法

首先观察:
Holder<B> h = new Holder<>(new B());

用Java 8和Java 7编译,并且都创建Holder< B>在那种情况下.所以使用<>使用带参数的构造函数很好.

然而:

Holder<A> h = new Holder<>(new B());

> Java 7首先评估右侧,确定它是Holder< B>.并给出编译错误,因为a Holder<B> can’t be converted into a Holder<A>.
> Java 8更进了一步,推断出新的Holder< A>(新的B())实际上可以工作并自动神奇地完成.这要归功于一项名为“目标打字”的新功能 – 请参阅the tutorial on type inference的最后一部分以获取概述.

更详细地说,Java 8的改进是由于引入了poly expressions(强调我的):

The type of a standalone expression can be determined entirely from the contents of the expression; in contrast,the type of a poly expression may be influenced by the expression’s target type (§5 (Conversions and Contexts)).

这是Java 8的一个非常强大的功能(Java 7仅提供不考虑表达式上下文的独立表达式).

泛型类实例创建是一个多义表达式,JLS #15.9解释(强调我的):

A class instance creation expression is a poly expression (§15.2) if it uses the diamond form for type arguments to the class,and it appears in an assignment context or an invocation context (§5.2,§5.3). Otherwise,it is a standalone expression.

由于新的规则,Java 8允许您使用上面的第二种形式,并自动推断新的B()应该被视为A(加宽参考转换),并且您打算创建一个Holder< A>.在这种情况下.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读