我試圖以一種通用的方式將BiFunction應用于方法引數,這樣我就可以從地圖中獲得該函式:
我試圖將BiFunction應用于方法引數。
public class ElementFactoryTest {
private final static Map<String,
BiFunction<
? extends Element,
弦樂。
? extends MetaElement<? extends MetaElement<?, ? >, ? extends Element>>>
functionMap = new HashMap<>()。
public static <
E extends Element,
M extends MetaElement<? extends MetaElement<?, ? >, ? extends Element> >
void registerFactoryFunction(String type, BiFunction<E, String, M> factoryFunction) {
functionMap.put(type, factoryFunction)。
}
public static <E extends Element>
MetaElement<?, ?> getElementList(String type, E element, String namespacePrefix) {
return functionMap.get(type).apply(element,namespacePrefix)。
}
}
registerFactoryFunction方法代碼編譯正常,但我不明白為什么這一行
return functionMap.get(type).apply(element, namespacePrefix) 。
不能編譯。是不是不能這樣做?
Update 1
按照@josejuan的建議,將extends改為super,可以編譯代碼,但是注冊雙函式的客戶端代碼卻無法編譯,出現了 "原因:型別不兼容。Element不能轉換為ElementSubclass":
ElementFactoryTest.registerElementFactory("elementType", MetaElementSubclass::build) 。
public static MetaElement<MetaElementSubclass, ElementSubclass> build(ElementSubclass element, String namespace){
....
}
更新2
下面是一個最小的可重復的例子:
public class ElementFactoryTest {
static class Parent {
public String getString() {
return "father"。
}
}
static class Child extends Parent {
public String getString() {
return "child"/span>。
}
private final static Map<String,
BiFunction<? super Parent, String, String> >
functionMap = new HashMap<>()。
public static void registerFactoryMethod( String type,
BiFunction<? super Parent, String, String> factoryFunction) {
functionMap.put(type, factoryFunction)。
}
public static <E extends Parent>
字串 getString(String type, E element, String namespacePrefix) {
return functionMap.get(type).apply(element,namespacePrefix)。
}
public static String build(Child child, String namespacePrefix) {
return namespacePrefix child.getString()。
}
public static void main(String[] args) {
ElementFactoryTest.registerFactoryMethod("child", ElementFactoryTest::build)。
String childString = ElementFactoryTest. getString("child", new Child(), "prefix。")。
}
該行:
ElementFactoryTest.registerFactoryMethod("child", ElementFactoryTest::build) 。
編譯失敗。
uj5u.com熱心網友回復:
你的代碼失敗是因為你的雙函式必須承認任何 編譯器試圖告訴你,你應該概括你的 在不知道你需要做什么的情況下,你最不壞的方法是在運行時降頻,但你原來的問題肯定承認有一個編譯時的解決方案(請不要編輯你的問題,如果你認為有必要的話,請創建另一個問題)。
用 有輸出 進一步閱讀: uj5u.com熱心網友回復: 在呼叫apply之前,我不得不對BiFunction進行鑄造,比如: 我不知道這是否是最好的解決方案,但這是唯一對我有效的解決方案。
最小的可重復的例子是:
標籤:? super Parent,但是你提供的實作只對Child super Parent有效。
Test::build函式。
public static String build(Parent child, String namespacePrefix){
if(child instanceof Child)
return namespacePrefix child.getString();
throw new RuntimeException("Arghh!)
System.out.println(Test. getString("child", new Child(), "prefix.") )。
System.out.println(Test.getString("child", new Parent(), "prefix.") ) 。
prefix.child
執行緒"main"java.lang.RuntimeException中出現例外。Arghh!
public static <E extends Parent>
字串 getString(String type, E element, String namespacePrefix) {
return ((BiFunction<E, String, String>) functionMap.get(type)).apply(element, namespacePrefix);
}
E被定義為E extends Parent,而BiFunction定義中的引數是? extends Parent,所以它看起來足夠合理。public class ElementFactoryTest {
static class Parent {
public String getString() {
return "father"。
}
}
static class Child extends Parent {
public String getString() {
return "child"/span>。
}
public static String build(Child child, String namespacePrefix) {
return namespacePrefix child.getString()。
}
}
static class GrandChild extends Child {
public String getString() {
return "grand child"。
}
public static String build(Child child, String namespacePrefix) {
return namespacePrefix child.getString()。
}
}
private final static Map<String,
BiFunction<? extends Parent, String, String> >
functionMap = new HashMap<>()。
public static <E extends Parent>
void registerElementFactory(String type,
BiFunction<E, String, String> factoryFunction) {
functionMap.put(type, factoryFunction)。
}
public static <E extends Parent>
字串 getString(String type, E element, String namespacePrefix) {
return ((BiFunction<E, String, String>) functionMap.get(type)).apply(element, namespacePrefix);
}
public static void main(String[] args){
ElementFactoryTest.registerElementFactory("child", Child::build)。
ElementFactoryTest.registerElementFactory("grand-child", GrandChild::build)。
String childString = ElementFactoryTest. getString("child", new Child(), "prefix。")。
System.out.println(childString)。
String grandChild = ElementFactoryTest. getString("grand-child", new GrandChild(), "prefix;)
System.out.println(grandChild)。
}
}

