爪哇8:参考[方法]是不明确的[复制]爪哇8:参考[方法]是不明确的[复制](Java 8: Ref

2019-05-12 03:42发布

这个问题已经在这里有一个答案:

  • Java类型推理:基准是不明确的在Java中8,但不是Java 7个 2答案

任何人都不会明白,为什么下面的代码将在Java 7中及以下编译罚款,但未能与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和低于该编译好并且选择与该对象参数的put方法。 在JDK 8这不能被编译,说明put方法是不明确的。

显然JDK 8跳过对象参数的方法,并找到最后两个子对象的参数的方法和抱怨他们(也就是说,如果你与其他一些参数类型添加其他put方法,编译器会切换并抱怨新的最后两种方法)

这似乎是一个错误。

Answer 1:

你的问题是广义靶式推理 ,在Java 8的改进的副作用。

什么是目标型推理

让我们把你方法的例子,

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

现在,在上述方法中,泛型参数R不能由编译器,因为有不带参数解析R

因此,他们引入了一个概念叫Target-type Inference ,它允许基于分配参数来推断的参数。

所以,如果你这样做,

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

这适用于Java 7中,但以下情况不

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

由于类型推断只是工作的直接分配。

如果没有直接分配,那么泛型类型被推断为Object

所以,当你的Java 7编译的代码,你put(Object)方法的调用没有任何问题。

他们在Java中没有8

他们改进了类型推断推断方法调用链接的方法调用的类型

关于他们的更多细节在这里和这里

所以,现在,你可以直接调用put(get("something"))和通用型根据的参数推断 put()方法

但你也知道,方法, put(Charsequence)put(char[])相匹配的参数。 因此,有歧义。

固定?

只是告诉你想要什么编译器,

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


Answer 2:

看起来这是一个已知的不兼容。

参见“区域:工具/ javac的”部分这篇文章。 而这个bug 。

概要

下面的代码,其编译,以警告,在JDK 7在JDK 8不会编译:

import java.util.List;

class SampleClass {

    static class Baz<T> {
        public static List<Baz<Object>> sampleMethod(Baz<Object> param) {
            return null;
        }
    }

    private static void bar(Baz arg) {
        Baz element = Baz.sampleMethod(arg).get(0);
    }
} 

在JDK 8编译此代码产生以下错误:

SampleClass.java:12: error:incompatible types: Object cannot be converted to Baz
    Baz element = Baz.sampleMethod(arg).get(0);

Note: SampleClass.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error 

在这个例子中,原始类型被传递给其可应用于由子类型的sampleMethod(巴兹)方法(见JLS,爪哇SE 7版,部分15.12.2.2)。

一个未经检查的转换是必要的方法是适用的,所以它的返回类型被擦除(见JLS,爪哇SE 7版,部分15.12.2.6)。 在这种情况下sampleMethod(巴兹)的返回类型是java.util.List的代替的java.util.List>从而得到(INT)的返回类型为对象,这是不分配兼容巴兹。



文章来源: Java 8: Reference to [method] is ambiguous [duplicate]