簡體   English   中英

構造函數模糊與java 8中的varargs

[英]Constructor ambiguity with varargs in java 8

在下面的類中,由於對this()的模糊調用,我得到了Java 8的編譯錯誤。 但是,使用Java 6,這個類編譯得很好。 我知道我可以使用工廠方法重構這個但是對於發生問題的實際類,我強烈希望現在維護當前的API。

有沒有人能想到一種方法來解決歧義而不改變外部API?

public class Vararg8 {

    public Vararg8(final Object... os) {}

    public Vararg8(final boolean b,
                   final String s,
                   final int... is) {}

    public Vararg8() {
        this(true, "test", 4, 5, 6);
    }
}

你可以通過傳遞一個顯式的int[]數組來做到這一點:

public Vararg8()
{
  this(true, "test", new int[]{4, 5, 6});
}

您可能會注意到,從某種意義上說,這仍然是模棱兩可的:您傳遞的內容仍然與Object...構造函數兼容。 這樣做的原因是方法分辨率處於不同階段,只有最后階段允許考慮varargs參數。 因為你已經使用了一個顯式數組,所以它可以很好地擊中第二個數組,而不需要擴展varargs。 沒有varargs擴展就無法擊中第一個,所以直到最后階段都不會考慮。

請參閱相應的JLS文檔

第一階段(§15.12.2.2)執行重載解析而不允許裝箱或拆箱轉換,或使用變量arity方法調用。 如果在此階段沒有找到適用的方法,則處理繼續到第二階段。

第二階段(§15.12.2.3)執行重載解析,同時允許裝箱和拆箱,但仍然排除使用變量arity方法調用。 如果在此階段沒有找到適用的方法,則處理繼續到第三階段。

第三階段(§15.12.2.4)允許重載與變量arity方法,裝箱和拆箱相結合。

試試這個:

public Vararg8()
{
  this(true, "test", new int[]{4, 5, 6});
}

使用顯式int數組應該可以解決您的問題。

  public Vararg8() {
        this(true, "test",new int[]{ 4, 5, 6});
    }

您可以使用generic在運行時推斷類型,但這會將它們轉換為Boxed形式。 這當然是性能神風,如果你在那里做了很多算術或必須打包很多原語,但會讓所有現有的代碼正常工作。

如果您已經使用了對象類型,那么此解決方案將不會為您帶來任何成本。

看起來像這樣:

public<A extends Boolean, B extends String, C extends Integer> Disambiguate(final A booleanPar,
                                        final B stringPar,
                                        final C... integerPar) {System.out.println("Im in the specific one");}

public<T extends Object> Disambiguate(final T... os) {System.out.println("Im in the general one");}

public static void main(String[] args) {
    new Disambiguate(true, "test", 4, 5, 6);
}

您可以將泛型用於1.5及更高版本的“向后兼容性”,並使所有現有代碼正常工作並創建一個新的Api,以避免將來出現此問題。

字符數組也解決了你的問題

public Vararg8() {
            this(true, "test".toCharArray(), 4, 5, 6);
        }

暫無
暫無

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

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