0

这段代码有什么问题?我需要创建一个依赖 BiFunction 的工厂方法来完成它的工作。

编译器告诉我:

The method apply(Class<T>, Supplier<I>) 
in the type BiFunction<Class<T>,Supplier<I>,T> 
is not applicable for the arguments (Class<A>, B::new)

但是 B 扩展了 A,B::new 为 B 生成了供应商 ...

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.function.BiFunction;
import java.util.function.Supplier;

import org.junit.jupiter.api.Test;

public class BiFunctionTest {

    static interface A {

    }

    static class B implements A {

    }

    static interface C {

    }

    static class D implements C {

    }

    private A a;
    private C c;

    public static <T, I extends T> BiFunctionTest create(
            BiFunction<Class<T>, Supplier<I>, T> fn) {
        BiFunctionTest o = new BiFunctionTest();
        o.a = fn.apply(A.class, B::new);
        o.c = fn.apply(C.class, D::new);
        return o;
    }

    @Test
    public void testBiFunction() {
        BiFunctionTest o = BiFunctionTest.create((i, s) -> s.get());
        assertEquals(B.class, o.a.getClass());
        assertEquals(D.class, o.c.getClass());
    }

}

4

3 回答 3

0

通过添加额外的接口解决了它,但需要强制转换..:/


import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.function.BiFunction;
import java.util.function.Supplier;

import org.junit.jupiter.api.Test;

public class BiFunctionTest {

    static interface A {
    }

    static interface B extends A {
    }

    static class ObjectB implements B {
    }

    static interface C extends A {
    }

    static class ObjectC implements C {
    }

    private B b;
    private C c;

    public static BiFunctionTest create3(
            BiFunction<Class<? extends A>, Supplier<? extends A>, A> fn) {
        BiFunctionTest o = new BiFunctionTest();
        o.b = (B) fn.apply(B.class, ObjectB::new);
        o.c = (C) fn.apply(C.class, ObjectC::new);
        return o;
    }

    @Test
    public void testBiFunction() {
        BiFunctionTest o = BiFunctionTest.create3((i, s) -> s.get());
        assertEquals(ObjectB.class, o.b.getClass());
        assertEquals(ObjectC.class, o.c.getClass());
    }

}
于 2019-03-29T21:58:05.887 回答
0

泛型必须完全匹配,除非明确声明,否则不会对它们进行协变/逆变检查。所以Supplier<B>不是 aSupplier<A>而是 a Supplier<? extends A>

然后您的签名将更改为以下内容:

 public static <T, I extends T> BiFunctionTest create(BiFunction<Class<? extends T>, Supplier<? extends I>, T> fn) {...

T但是现在对于第二个问题,就您使用A.classand而言,您的函数主体不是通用的B::new。如果实现确实不依赖于这些类型,则应使用此处的通用签名AB但事实并非如此。

所以从签名中删除泛型:

public static BiFunctionTest create(BiFunction<Class<? extends A>, Supplier<? extends A>, A> fn) {...

我们有您提供的正文的适当签名:

    BiFunctionTest o = new BiFunctionTest();
    o.a = fn.apply(A.class, B::new);
    return o;
于 2019-03-29T18:22:21.740 回答
0
 public static <T> BiFunctionTest create2(
        BiFunction<Class<T>, Supplier<T>, T> fn) {
    BiFunctionTest o = new BiFunctionTest();
    Supplier<A> u = B::new;
    o.a = fn.apply(A.class, u);
    Supplier<? extends C> u2 = D::new;
    o.c = fn.apply(C.class, u2);
    return o;
}

@Test
public void testBiFunction() {
    BiFunctionTest o = BiFunctionTest.create2((i, s) -> s.get());
    assertEquals(B.class, o.a.getClass());
    assertEquals(D.class, o.c.getClass());
}

生产

The method apply(Class<T>, Supplier<T>) 
in the type BiFunction<Class<T>,Supplier<T>,T> 
is not applicable for the arguments (Class<BiFunctionTest.A>, Supplier<BiFunctionTest.A>)

The method apply(Class<T>, Supplier<T>) 
in the type BiFunction<Class<T>,Supplier<T>,T> 
is not applicable for the arguments (Class<BiFunctionTest.C>, Supplier<capture#1-of ? extends BiFunctionTest.C>)
于 2019-03-29T19:12:12.127 回答