我想建立一个API,客户端可以注册一个监听器,它接收事件。在事件上调用的侦听器方法需要一个参数。 API应该让客户决定这个参数应该是具体类的实例还是接口的实例(以避免客户端监听器实现中不必要的转换)。要做到这一点,我玩过泛型。它工作正常,除了一个案例!返回的工厂方法Builder不能用泛型编译。哪里不对?
客户端实现一个接口(请参阅MyListener1Impl.java和MyListener2Impl.java中的示例),并且可以使用泛型来决定事件的参数类型。
静态工厂方法用于检索ClassABuilder.java的实例。 ClassBuilder的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
}
}
对于一个问题,这是非常多的代码。你能把它降到最低吗? –
这似乎是[为什么隐式类型推断仅适用于赋值?]的副本?(http://stackoverflow.com/questions/2055352/why-implicit-type-inference-only-works-in-an-assignment ),[由编译器自动绑定(类型推断)的泛型类型](http://stackoverflow.com/questions/4143796/auto-binding-type-inference-of-generic-types-by-the-compiler),或者[泛型类型推断失败?](http://stackoverflow.com/questions/4149825/generics-type-inference-fails)。 –