返回Builder的工厂方法不使用泛型进行编译。怎么了?
|
我正在尝试构建一个API,客户端可以在其中注册接收事件的侦听器。在事件上调用的侦听器方法带有一个参数。 API应该让客户端决定该参数是具体类的实例还是接口的实例(以避免在客户端侦听器实现中进行不必要的强制转换)。为此,我使用了泛型。正常,除了一种情况!
客户端实现一个接口(请参见MyListener1Impl.java和MyListener2Impl.java中的示例),并且可以使用泛型来确定事件的参数类型。
静态工厂方法用于检索ClassABuilder.java的实例。 ClassABuilder \的build()方法返回ClassA.java的实例
由于某种原因,当将Factory方法与Builder模式一起使用(以伸缩形式调用方法)并且将具体的侦听器实现用作泛型类型参数时,它将无法编译(请参阅变量\“ c4 \”是组)。谁能告诉我为什么?怎么了?
请参阅下面的完整示例代码。将以下类复制/粘贴到Eclipse(或任何其他IDE)中,您将看到它无法编译的位置。
Main.java类
public class Main{
public static void main(String[] args){
// Works ok when generic type argument is set to interface \"AnyFile\".
// MyListener2Impl has also declared \"AnyFile\"
ClassABuilder<AnyFile> builder0 = Factory.newClassABuilder();
builder0.set(new MyListener2Impl());
ClassA<AnyFile> c0 = builder0.build();
// Also Works ok when methods are called in telescope form
// (not sure \"telescope\" is the correct term?)
ClassA<AnyFile> c1 = Factory.newClassABuilder()
.set(new MyListener2Impl())
.build();
// Works ok when generic type argument is set to concrete \"MyFileImpl\".
// MyListener1Impl has also declared \"MyFileImple\"
ClassABuilder<MyFileImpl> builder2 = Factory.newClassABuilder();
builder2.set(new MyListener1Impl());
ClassA<MyFileImpl> c2 = builder2.build();
// also works ok with telescop form, but Factory class is NOT used.
ClassA<MyFileImpl> c3 = new ClassABuilder<MyFileImpl>().set(new MyListener1Impl()).build();
// But with static factory method AND telescope style, it does not compile! Why? What is wrong?
ClassA<MyFileImpl> c4 = Factory.newClassABuilder()
.set(new MyListener1Impl())
.build();
}
}
类AnyFile.java
import java.util.List;
public interface AnyFile {
List<AnyFile> listFiles();
}
ClassA.java类
public class ClassA <T extends AnyFile>{
}
ClassABuilder.java类
public class ClassABuilder <T extends AnyFile>{
public ClassABuilder<T> set(Listener<T> a){
return this;
}
public ClassA<T> build(){
return new ClassA<T>();
}
}
类Factory.java
public class Factory {
public static <T extends AnyFile> ClassABuilder<T> newClassABuilder(){
return new ClassABuilder<T>();
}
}
Listener.java类
public interface Listener <T extends AnyFile>{
void event(T file);
}
类MyFileImpl.java
import java.util.List;
public class MyFileImpl implements AnyFile{
@Override
public List<AnyFile> listFiles() {
// do something...
return null;
}
}
类MyListener1Impl.java
public class MyListener1Impl implements Listener<MyFileImpl>{
@Override
public void event(MyFileImpl file) {
// do something
}
}
类MyListener1Impl.java
public class MyListener2Impl implements Listener<AnyFile>{
@Override
public void event(AnyFile file) {
// do something
}
}
没有找到相关结果
已邀请:
1 个回复
蜗仓馈
方法之前,必须知道ѭ10the的类型
(将用于参数化
),并且Java无法从在该返回类型上调用的方法的参数推断出
的返回类型。 这种推断需要整个程序的分析,很少有语言会这样做,而Java绝对不支持。