假设我有以下课程:
import java.util.function.Function
import java.util.List
class Foo<X, Y> {
public Function<X, Y> converter;
public List<X> inputs;
public Foo(Function<X, Y> converter, List<X> inputs) {
this.converter = converter;
this.inputs = inputs;
}
}
我想添加一个构造函数,该构造函数接受List<X>
个输入,并自动提供一个标识函数以与其一起使用:
public Foo(List<X> inputs) {
this(Function.identity(), inputs);
}
但是,这给了我一个错误:The constructor Foo<X, Y>(Function<Object,Object>, List<X>) is undefined
。
另一方面,以下编译:
public static <X> Foo<X, X> makeFoo(List<X> inputs) {
return new Foo<>(Function.identity(), inputs);
}
事实上,以下内容也有效:
public Foo(List<X> inputs) {
this.converter = (Function<X, Y>)Function.identity();
this.inputs = inputs;
}
然而,我必须在Function<Object, Object> to Function<X, Y>
进行未经检查的演员表。它会起作用,但我了解到通常有一种方法可以处理不需要转换的泛型(或Java中的任何东西)。
有没有办法让构造函数使用它而不是使用静态方法或者转换?
我尝试使用this((Function<X, X>)Function.identity(), inputs)
调用其他构造函数,将构造函数重写为public Foo<X, X>(List<X> inputs)
,并使用<X, X>this(Function.identity(), inputs)
调用其他构造函数,但无效。
似乎应该有一种方法让编译器知道Function.identity()
参数或Foo
创建的类型<X, X>
类型,但我不能想出任何好的地方。我环顾四周,找不到以任何方式强制转换或指定类型的方法。我能找到的最接近主题的是类型证人,&#34; BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);
&#34;来自here,但这似乎是一个不同的场景。还有一些有趣的&#34; new <TypeWitnessForConstructor> Box<TypeArgumentsForInstance>(...)
&#34;来自this SO回答的建议,但这似乎也不适用。我认为原因既不适用也是因为我的构造函数没有任何类型参数,例如public <Z> Foo(...)
。
感谢您的帮助。
答案 0 :(得分:3)
不,没有更好的方法。您不能将此构造函数限制为仅在X
和Y
相同类型时才起作用,因此构造函数必须假设它们不同,并且Function.identity()
相应地不一定是正确的类型。
也就是说,使用静态工厂方法通常比暴露构造函数更好,如果你这样做,你会没事的。