在访问者模式中使用 java 泛型时,我遇到了一些麻烦。
我的代码是这样的:
public interface MyInterfaceVisitor<A, B> {
public A visitMyConcreteObject(MyConcreteObject object, B parameter);
}
public interface MyObject {
public <A, B> A accept(MyInterfaceVisitor<A, B> visitor, B parameter);
}
public class MyConcreteObject implements MyObject {
@Override
public <A, B> A accept(MyInterfaceVisitor<A, B> visitor, B parameter) {
return visitor.visitMyConcreteObject(this, parameter);
}
}
public class MyConcreteVisitor implements MyInterfaceVisitor<????> {
@Override
public <X extends C> X visitMyConcreteObject(MyConcreteObject object, Class<X> parameter) {
// Do a lot of things.
// Return an instance of the given class.
}
// This method is the entry point of the MyConcreteVisitor.
public <X extends C> void someOtherMethod(Class<X> parameter) {
MyObject m = ...;
X x = m.accept(this, parameter);
...;
}
}
public class C {}
public class Dog extends C {}
public class Cat extends C {}
public class Client {
public static void main(String... args) {
MyConcreteVisitor v = new MyConcreteVisitor();
v.someOtherMethod(Cat.class);
v.someOtherMethod(Dog.class);
}
}
// We have other implementations of the visitor that does not matters, like this one.
public class SomeOtherConcreteVisitor implements MyInterfaceVisitor<String, Integer> {
@Override
public String visitMyConcreteObject(MyConcreteObject object, Integer parameter) {
return "foo";
}
}
我需要找到什么是通用签名????这使得代码可编译,允许 MyConcreteVisitor 类中的重写方法与 MyInterfaceVisitor 接口中的签名匹配。
我无法更改 MyInterfaceVisitor 接口中 visitMyObject 的签名,也无法更改其泛型。发生这种情况是因为存在 MyInterfaceVisitor 的其他实现,并且它们的泛型与来自 MyConcreteVisitor 的泛型无关。
MyConcreteVisitor 类本身不应具有泛型,因此编译器必须允许 aMyConcreteVisitor v = new MyConcreteVisitor();
而不会生成 unchecked 或 rawtypes 警告。
如果我将具体的 visitMyObject 更改为public C visitMyObject(MyObject object, Class<? extends C> parameter)
并声明 ???? 因为<C, Class<? extends C>>
,我需要在 someOtherMethod 中添加一个演员表。
如何定义泛型类型使其可编译,而不会收到未经检查或 rawtypes 警告、更改接口或添加强制转换?这在java中是否可能,或者我滥用泛型太多了?