无法编译java源程序_泛型 - 为什么这个Java 8程序无法编译?

在Java 8中更改了类型推断。现在,对于构造函数和方法,类型推断同时查看目标类型和参数类型。 考虑以下:

interface Iface {}

class Impl implements Iface {}

class Impl2 extends Impl {}

class Acceptor {

public Acceptor(T obj) {}

}

T foo(T a) { return a; }

以下现在在Java 8中可以正常(但在Java 7中没有):

Acceptor a = new Acceptor<>(new Impl2());

// Java 8 cleverly infers Acceptor

// While Java 7 infers Acceptor (causing an error)

当然,这在以下两个方面都给出了错误:

Acceptor a = new Acceptor(new Impl2());

这在Java 8中也可以:

Acceptor a = foo (new Acceptor<>(new Impl2()));

// Java 8 infers Acceptor even in this case

// While Java 7, again, infers Acceptor

// and gives: incompatible types: Acceptor cannot be converted to Acceptor

以下两者都给出了错误,但错误不同:

Acceptor a = foo (new Acceptor(new Impl2()));

// Java 7:

// incompatible types: Acceptor cannot be converted to Acceptor

// Java 8:

// incompatible types: inferred type does not conform to upper bound(s)

// inferred: Acceptor

// upper bound(s): Acceptor,java.lang.Object

显然,Java 8使类型推理系统更加智能化。 这会导致不兼容吗? 一般来说,没有。 由于类型擦除,只要程序编译,实际上并不重要的是推断出什么类型。 Java 8是否编译所有Java 7程序? 它应该,但你提出了一个案例,但它没有。

似乎正在发生的事情是Java 8没有很好地处理通配符。 它似乎将它们视为一种它无法满足的限制性约束,而不是将它们视为缺乏约束。 我不确定它是否跟随JLS的信件,但我至少在精神上称这是一个bug。

仅供参考,这确实有效(请注意,我的Acceptor没有您的类型限制):

Acceptor> a = new Acceptor<>(new Impl2());

请注意,您的示例在方法参数之外使用通配符类型(这是不可取的),我想知道在方法调用中使用菱形运算符的更典型代码中是否会出现相同的问题。 (大概。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值