java 8 泛型,Java 8类型推断导致在调用时省略泛型类型

升级到

Java 1.8后,我遇到了一个泛型方法的问题,这对于Java 1.6和1.7来说很好

请考虑以下代码:

public class ExtraSortList extends ArrayList {

ExtraSortList(E... elements) {

super(Arrays.asList(elements));

}

public List sortedCopy(Comparator super E> c) {

List sorted = new ArrayList(this);

Collections.sort(sorted, c);

return sorted;

}

public static void main(String[] args) {

ExtraSortList stringList = new ExtraSortList<>("foo", "bar");

Comparator super String> compGen = null;

String firstGen = stringList.sortedCopy(compGen).get(0); // works fine

Comparator compRaw = null;

String firstRaw = stringList.sortedCopy(compRaw).get(0); // compiler ERROR: Type mismatch: cannot convert from Object to String

}

}

我尝试使用Oracle javac(1.8.0_92)和Eclipse JDT(4.6.1)编译器.两者都是一样的结果. (错误消息有点不同,但基本相同)

除了事实,可以通过避免原始类型来防止错误,它让我困惑,因为我不明白原因.

为什么sortedCopy-Method的raw方法参数对返回值的泛型类型有任何影响?泛型类型已在类级别定义.该方法未定义单独的泛型类型.引用列表的类型为< String>,返回的List也应如此.

为什么Java 8会在返回值上丢弃类中的泛型类型?

编辑:如果sortedCopy的方法签名被更改(由biziclop指出)

public List sortedCopy(Comparator c) {

那么编译器确实从类型ExtraSortList< E>中考虑通用类型E.并且不会出现错误.但是现在参数c是原始类型,因此编译器无法验证提供的Comparator的泛型类型.

编辑:我做了一些Java语言规范的评论,现在我想一想,我是否缺乏理解,或者这是编译器的一个缺陷.因为:

> Scope of a Declaration的泛型类型E是ExtraSortList类,它包括方法sortedCopy.

>方法sortedCopy本身不声明泛型类型变量,它只是从类范围引用类型变量E.见JLS中的Generic Methods

> JLS也在同一部分中说明

Type arguments may not need to be provided explicitly when a generic method is invoked, as they can often be inferred (§18 (Type Inference)).

>引用stringList是使用String定义的,因此编译器不需要在sortedCopy的调用中推断类型forE,因为它已经定义.

>因为stringList已经具有E的具体类型,所以参数c应该是Comparator对于给定的调用.

>返回类型也应该使用已经具体化的类型E,因此它应该是List< String>.

这是我目前对我认为Java编译器应如何评估调用的理解.如果我错了,解释为什么我的假设是错误的将是很好的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值