簡體   English   中英

Java 8泛型函數應該是模糊的,但在運行時失敗

[英]Java 8 generic function should be ambiguous, but failing in runtime

我正在嘗試將Java 7代碼遷移到Java 8,所以我的代碼類似於:

package tests;

import java.util.Arrays;
import java.util.Map;

public class Tests {
    private static interface ComparableMap<K,V> extends Map<K,V>, Comparable {}

    public static void main(String[] args) {
        func(getString());
    }

    private static void func(Comparable...input){
        System.out.println(Arrays.toString(input));
    }

    private static void func(ComparableMap <?,?> m){
        System.out.println(m);
    }

    private static <T extends Comparable> T getString(){
        return (T) "aaa";
    }
}

在java 7中它正常工作,在Java 8中我得到:

java.lang.ClassCastException:java.lang.String無法強制轉換為tests.Tests $ ComparableMap

如果我將一個函數定義更改為:

    private static <T> T getString(){
        return (T) "aaa";
    }

編譯將失敗:錯誤:

對func的引用含糊不清

為什么Java 8編譯器在第一種情況下沒有失敗? (看起來對我來說是錯誤的)是否可以更改第二個重載函數,以便在不更改調用本身的情況下使用varargs參數調用第一個函數?

編譯器錯誤

在第一種情況下,需要方法getString來返回Comparable實例。 編譯器查找func方法的重載,它只找到一個可以接受Comparablefunc(Comparable ... input) Map沒有實現該接口,因此第二個重載不適用。 沒有含糊之處。

在第二種情況下, getString可以返回任何內容。 這兩個重載都有效,因此存在歧義。 但請注意,在兩種情況下,對T的強制轉換都是不安全/錯誤的。

美國演員

你編寫的泛型方法基本上告訴編譯器“我可以返回你想要實現Comparable的任何類的實例”。 但你實際上不能遵守這個承諾。

可以說我有以下代碼:

String str = getString();
Integer num = getString();

這段代碼將編譯, StringInteger實現Comparable接口。 第二行在運行時會失敗:代碼嘗試將String轉換為Integer

你的第二個案例也是錯誤的,原因與我上面解釋的相同。 它承諾它可以返回任何你想要的類型 它似乎也不能保持這個承諾( Runnable這里是一個隨機的例子,它可以是任何東西):

Runnable run = getString()

您更新的代碼

編譯器看到兩個可能的重載,它們都匹配, func(Comparable...input)func(ComparableMap <?,?> m) 它更喜歡第二個,因為varargs方法總是最后選擇( 出於競爭性原因 )。 所有這些都是核心行為。

然后代碼拋出ClassCastException,因為你的getString方法沒有保證它的承諾(讓調用者決定返回什么類型的Comparable )。

怎么解決?

根本問題是你的getString方法犯了一個假承諾。 因此,我真的不知道該代碼試圖完成什么。 如果你能詳細說明,我們可以幫助你進一步發展。

是的,我不知道為什么Java 8會選擇帶有映射的重載超過采用Comparable vararg的映射。 我猜這個好的老式擦除在這里發揮作用。

也就是說,我只是讓getString()返回一個Comparable而不是T

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM