gpt4 book ai didi

Java 7 菱形运算符和派生类的初始化

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:01:54 26 4
gpt4 key购买 nike

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 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 允许您使用上面的第二种形式并自动推断出 new B()应该被视为 A (扩大引用转换)并且你打算创建一个 Holder<A>在这种情况下。

关于Java 7 菱形运算符和派生类的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23528218/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com