簡體   English   中英

Java泛型方法調用

[英]Java ambiguous method call with generics

以下示例中的Java泛型模棱兩可的方法調用:

public class Foo {

    public <Y, X extends Y> void set(Path<Y> attribute, X value) {
        ...
    }

    public <Y> void set(Path<Y> attribute, Expression<? extends Y> value) {
        ...
    }
}

嘗試調用第二種方法

    Foo foo = new Foo();
    Path<Object> path = new Path<Object>();
    foo.set(path, new Expression<Object>(value));

在Eclipse內部,沒有錯誤。 但是在命令行上,編譯錯誤:

error: reference to set is ambiguous
                foo.set(path, new Expression<Object>(value));
                       ^
  both method <Y#1,X>set(Path<Y#1>,X) in Foo and method <Y#2>set(Path<Y#2>,Expression<? extends Y#2>) in Foo match
  where Y#1,X,T,Y#2 are type-variables:
    Y#1 extends Object declared in method <Y#1,X>set(Path<Y#1>,X)
    X extends Y#1 declared in method <Y#1,X>set(Path<Y#1>,X)
    T extends Object declared in class Foo
    Y#2 extends Object declared in method <Y#2>set(Path<Y#2>,Expression<? extends Y#2>)

如何調用第二種方法?

無法強制編譯器選擇該方法的任何一個版本。 如評論中所述,明智的做法是簡單地以不同的方式調用這兩種方法。

也許您應該考慮定義一個更復雜的Expression方法的單一方法,並在必要時定義僅返回給定常數值的表達式。

我認為您應該考慮使用lambda或Supplier<X>來支持這些表達式:

public <X> void set(Path<X>, Supplier<? extends X> expression) {
    // ...
    X value = expression.get();
    // ...
}

然后:

final Path1<Integer> daysInAWeek = ...;
final Path2<Date> today = ...; 
foo.set(daysInAWeek, () -> 7); // the constant value returning expression.
foo.set(today, () -> Date.todaysDate()); // calculated when invoked.

這些foo.set代碼行中的每行都隱式聲明一個擴展Supplier的內部類。 您還可以創建命名的頂級類,這些類實現Supplier並將實例作為set的第二個參數傳遞。

另外,如果您堅持要擁有自己的Expression接口/類,並且該接口/類只要符合作為功能接口的條件即可,例如Supplier

暫無
暫無

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

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