4 回答

TA貢獻1828條經驗 獲得超3個贊
在第一個示例中,和MyInterface::getLength分別幫助"I am NOT an Integer"解析通用參數T和。RMyInterfaceSerializable & Comparable<? extends Serializable & Comparable<?>>
// it compiles since String is a Serializable
Function<MyInterface, Serializable> function = MyInterface::getLength;
Builder.of(MyInterface.class).with(function, "I am NOT an Integer");
MyInterface::getLength并不總是 a ,Function<MyInterface, Integer>除非您明確這么說,這會導致編譯時錯誤,如第二個示例所示。
// it doesn't compile since String isn't an Integer
Function<MyInterface, Integer> function = MyInterface::getLength;
Builder.of(MyInterface.class).with(function, "I am NOT an Integer");

TA貢獻1875條經驗 獲得超3個贊
類型推斷在這里發揮了作用。R
考慮方法簽名中的泛型:
<R> Builder<T> with(Function<T, R> getter, R returnValue)
在所列情況中:
Builder.of(MyInterface.class).with(MyInterface::getLength, "I am NOT an Integer");
的類型R
被成功推斷為
Serializable, Comparable<? extends Serializable & Comparable<?>>
并且 aString
確實通過這種類型暗示,因此編譯成功。
要顯式指定 的類型R
并找出不兼容性,只需將代碼行更改為:
Builder.of(MyInterface.class).<Integer>with(MyInterface::getLength, "not valid");

TA貢獻1839條經驗 獲得超15個贊
這是因為你的泛型類型參數R
可以被推斷為 Object,即以下編譯:
Builder.of(MyInterface.class).with((Function<MyInterface, Object>) MyInterface::getLength, "I am NOT an Integer");

TA貢獻1772條經驗 獲得超6個贊
這個答案基于其他答案,這些答案解釋了為什么它不能按預期工作。
解決方案
下面的代碼通過將雙函數“with”拆分為兩個連貫函數“with”和“returning”來解決該問題:
class Builder<T> {
...
class BuilderMethod<R> {
final Function<T, R> getter;
BuilderMethod(Function<T, R> getter) {
this.getter = getter;
}
Builder<T> returning(R returnValue) {
return Builder.this.with(getter, returnValue);
}
}
<R> BuilderMethod<R> with(Function<T, R> getter) {
return new BuilderMethod<>(getter);
}
...
}
MyInterface z = Builder.of(MyInterface.class).with(MyInterface::getLength).returning(1L).with(MyInterface::getNullLength).returning(null).build();
System.out.println("length:" + z.getLength());
// YIPPIE COMPILATION ERRROR:
// The method returning(Long) in the type BuilderExample.Builder<BuilderExample.MyInterface>.BuilderMethod<Long> is not applicable for the arguments (String)
MyInterface zz = Builder.of(MyInterface.class).with(MyInterface::getLength).returning("NOT A NUMBER").build();
System.out.println("length:" + zz.getLength());
(有點陌生)
添加回答
舉報