java 报错 对put的引用不明确,Java类型推断:引用在Java 8中是不明确的,但不是Java 7...

Lets say we have 2 classes. An empty class Base, and a subclass of this class Derived.

public class Base {}

public class Derived extends Base {}

Then we have a few methods in another class:

import java.util.Collection

public class Consumer {

public void test() {

set(new Derived(), new Consumer().get());

}

public T get() {

return (T) new Derived();

}

public void set(Base i, Derived b) {

System.out.println("base");

}

public void set(Derived d, Collection extends Consumer> o) {

System.out.println("object");

}

}

This compiles and runs successfully in Java 7, but does not compile in Java 8. The error:

Error:(8, 9) java: reference to set is ambiguous

both method set(Base,Derived) in Consumer and

method set(Derived,java.util.Collection) in Consumer match

Why does work in Java 7, but not Java 8? How could ever match Collection?

解决方案

The problem is that the type inference has been improved. You have a method like

public T get() {

return (T) new Derived();

}

which basically says, “the caller can decide what subclass of Base I return”, which is obvious nonsense. Every compiler should give you an unchecked warning about your type cast (T) here.

Now you have a method call:

set(new Derived(), new Consumer().get());

Recall that your method Consumer.get() says “the caller can decide what I return”. So it’s perfectly correct to assume that there could be a type which extends Base and implement Collection at the same time. So the compiler says “I don’t know whether to call set(Base i, Derived b) or set(Derived d, Collection extends Consumer> o)”.

You can “fix” it by calling set(new Derived(), new Consumer().get()); but to illustrate the madness of your method, note that you can also change it to

public > void test() {

set(new Derived(), new Consumer().get());

}

which will now call set(Derived d, Collection extends Consumer> o) without any compiler warning. The actual unsafe operation happened inside the get method.

So the correct fix would be to remove the type parameter from the get method and declare what it really returns, Derived.

By the way, what irritates me, is your claim that this code could be compiled under Java 7. Its limited type inference with nested method calls leads to treating the get method in a nested invocation context like returning Base which can’t be passed to a method expecting a Derived. As a consequence, trying to compile this code using a conforming Java 7 compiler will fail as well, but for different reasons.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值