なぜ、このJavaメソッドの呼び出しが曖昧と考えられていますか?

jigawot:

私は私が間違っている可能性があります信じて奇妙なエラーメッセージに遭遇しました。次のコードを考えてみます。

public class Overloaded {
    public interface Supplier {
        int get();
    }

    public interface Processor {
        String process(String s);
    }

    public static void load(Supplier s) {}
    public static void load(Processor p) {}

    public static int genuinelyAmbiguous() { return 4; }
    public static String genuinelyAmbiguous(String s) { return "string"; }

    public static int notAmbiguous() { return 4; }
    public static String notAmbiguous(int x, int y) { return "string"; }

    public static int strangelyAmbiguous() { return 4; }
    public static String strangelyAmbiguous(int x) { return "string"; }
}

私はこのような方法でそのルックスを持っている場合:

// Exhibit A
public static void exhibitA() {
    // Genuinely ambiguous: either choice is correct
    load(Overloaded::genuinelyAmbiguous); // <-- ERROR
    Supplier s1 = Overloaded::genuinelyAmbiguous;
    Processor p1 = Overloaded::genuinelyAmbiguous; 
}

我々が得るエラーは完璧な理にかなっています。パラメータはload()、我々はメソッドの呼び出しがあいまいであるというエラーを取得するので、どちらかに割り当てることができます。

逆に、私はこのようになりますというメソッドを持っている場合:

// Exhibit B
public static void exhibitB() {
    // Correctly infers the right overloaded method
    load(Overloaded::notAmbiguous);
    Supplier s2 = Overloaded::notAmbiguous;
    Processor p2 = Overloaded::notAmbiguous; // <-- ERROR
}

呼び出しはload()結構です、そして予想通り、私は両方の方法参照を割り当てることはできませんSupplierし、Processorそれがあいまいではないので:Overloaded::notAmbiguousに割り当てることはできませんp2

そして今、奇妙な1。私はこのようなメソッドを持っている場合:

// Exhibit C
public static void exhibitC() {
    // Complains that the reference is ambiguous
    load(Overloaded::strangelyAmbiguous); // <-- ERROR
    Supplier s3 = Overloaded::strangelyAmbiguous;
    Processor p3 = Overloaded::strangelyAmbiguous; // <-- ERROR
}

コンパイラはへの呼び出しは、と文句を言いますload()(あいまいであるerror: reference to load is ambiguous)が、とは異なり別紙A、私は両方のメソッド参照を割り当てることはできませんSupplierProcessorそれは本当に曖昧だったら、私は私が割り当てることができるはず感じるs3p3ちょうど別紙Aのように、両方のオーバーロードされたパラメータの型に、私は上のエラーを取得するp3ことを述べますerror: incompatible types: invalid method reference別紙Cで、この2番目のエラーは、理にかなってOverloaded::strangelyAmbiguous いないに割り当て可能なProcessor、それが割り当て可能でない場合は、なぜそれがまだ曖昧と考えられていますか?

選択するために、オーバーロードされたバージョンを決定する際にメソッド参照の推論だけFunctionalInterfaceのアリティを見ていることと思われます。変数割り当て、アリティに及びパラメータの種類オーバーロードされたメソッドと変数割り当ての間のこの不一致を引き起こす、チェックされます。

これはバグのように私には思えます。それがない場合には二つの選択肢の間で一つだけが正しいあいまいが間違いなく存在しないため、少なくとも、エラーメッセージは、間違っています。

オレクサンドルPyrohov:

あなたの質問は非常によく似ている、この 1。

短い答えは:

Overloaded::genuinelyAmbiguous;
Overloaded::notAmbiguous;
Overloaded::strangelyAmbiguous;

すべてのこれらのメソッドの参照は、(彼らは複数のオーバーロードを持っている)不正確です。したがって、に従ってJLS§15.12.2.2。、彼らは曖昧になり、過負荷解像度、中に適用チェックからスキップされます。

このケースでは、例えば、明示的に型を指定する必要があります。

load((Processor) Overloaded::genuinelyAmbiguous);
load(( Supplier) Overloaded::strangelyAmbiguous);

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=228966&siteId=1