Java 8:对 [method] 的引用不明确 [英] Java 8: Reference to [method] is ambiguous

查看:31
本文介绍了Java 8:对 [method] 的引用不明确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁明白为什么下面的代码在 Java 7 及更低版本中可以正常编译,但在 Java 8 中却失败了.

Does anybody understand why the following code will compile fine in Java 7 and below, but fails with Java 8.

public static void main(String[] args) throws Exception {
    put(get("hello"));
}

public static <R> R get(String d) {
    return (R)d;
}

public static void put(Object o) {
    System.err.println("Object " + o);
}

public static void put(CharSequence c) {
    System.err.println("CharSequence " + c);
}

public static void put(char[] c) {
    System.err.println("char[] " + c);
}

get 方法有一个通用的返回类型.在 JDK 7 及以下版本中,此编译良好,并选择了带有 Object 参数的 put 方法.在JDK 8中无法编译,说明put方法不明确.

The get method has a generic return type. In JDK 7 and below this compiles fine and the put method with the Object parameter is chosen. In JDK 8 this cannot be compiled, indicating the put method is ambiguous.

显然 JDK 8 正在跳过 Object-parameter 方法并找到最后两个子 Object-parameter 方法并抱怨它们(即,如果您添加另一个具有其他参数类型的 put 方法,编译器将切换并抱怨新的最后两种方法)

Apparently JDK 8 is skipping over the Object-parameter method and finding the last two sub-Object-parameter methods and complaining about them (i.e. if you add another put method with some other parameter type, the compiler will switch and complain about the new last two methods)

这似乎是一个错误.

推荐答案

您的问题是 Generalized Target-type Inference(Java 8 中的一项改进)的副作用.

Your problem is a side-effect of Generalized Target-type Inference, an improvement in Java 8.

让我们以您的示例方法为例,

Let's take your example method,

public static <R> R get(String d) {
    return (R)d;
}

现在,在上面的方法中,编译器无法解析泛型参数R,因为没有带有R的参数.

Now, in the method above, the generic parameter R cannot be resolved by the compiler because there's no parameter with R.

因此,他们引入了一个名为Target-type Inference的概念,它允许根据分配参数推断参数.

So, they introduced a concept called Target-type Inference, which allows the parameter to be inferred based on the assignment parameter.

所以,如果你这样做了,

So, if you do,

 String str = get("something"); // R is inferred as String here
 Number num = get("something"); // R is inferred as Number here

这在 Java 7 中运行良好.但以下不行

This works well in Java 7. But the following does not,

put(get("something");
static void Put(String str) {} //put method

因为类型推断仅适用于直接赋值.

Because type inference worked only for direct assignments.

如果没有直接赋值,则泛型类型被推断为Object.

If there's no direct assignment, then the generic type was inferred as Object.

因此,当您使用 Java 7 编译代码时,您的 put(Object) 方法被毫无问题地调用.

So, when you compiled the code with Java 7, your put(Object) method was called without any problems.

他们改进了类型推断,以从方法调用链式方法调用

有关它们的更多详细信息此处这里

More details about them here and here

所以现在,你可以直接调用put(get("something")),泛型类型将根据参数推断code>put() 方法.

So now, you can directly call put(get("something")) and the generic type will be inferred based on the parameter of the put() method.

但如您所知,方法 put(Charsequence)put(char[]) 匹配参数.所以存在歧义.

But as you know, the methods, put(Charsequence) and put(char[]) match the arguments. So there's the ambiguity.

直接告诉编译器你想要什么,

Just tell the compiler exactly what you want,

put(TestClass.<CharSequence>get("hello")); // This will call the put(CharSequence) method.

这篇关于Java 8:对 [method] 的引用不明确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆