Java 使用有界类型变量时参数不匹配
该守则已简化如下: 给定两个Java类文件Edge.Java和Node.Java,每个泛型类都有两个类型参数N和E。类型参数分别与上界泛型类型Node和Edge绑定 Node.java:Java 使用有界类型变量时参数不匹配,java,class,generics,types,Java,Class,Generics,Types,该守则已简化如下: 给定两个Java类文件Edge.Java和Node.Java,每个泛型类都有两个类型参数N和E。类型参数分别与上界泛型类型Node和Edge绑定 Node.java: public class Node<N extends Node<N, E>, E extends Edge<N, E>> { public void test(E edge) { // do something... } } 因此,其中一个
public class Node<N extends Node<N, E>, E extends Edge<N, E>> {
public void test(E edge) {
// do something...
}
}
因此,其中一个上限节点被更改为原始类型。它进行编译,但给出了警告:
$ javac Node.java Edge.java -Xlint:unchecked
Edge.java:3: warning: [unchecked] unchecked call to test(E) as a member of the raw type Node
src.test(this);
^
where E,N are type-variables:
E extends Edge<N,E> declared in class Node
N extends Node<N,E> declared in class Node
1 warning
$javac Node.java Edge.java-Xlint:未选中
java:3:警告:[未选中]未选中对作为原始类型节点成员的测试(E)的调用
src.试验(本);
^
其中E,N是类型变量:
扩展类节点中声明的边
N扩展类节点中声明的节点
1警告
它可以工作,但是我会丢失泛型类型,警告可能会导致将来的问题。下面是我的三个问题:
Edge
已经用它自己的类型参数化了。编译以下子类时不会出错,同时违反了this
是E
的假设:
class EdgeImpl1 extends Edge<NodeImpl, EdgeImpl2> {}
src.test((E)this);
如果self类型被误用,这可能会导致ClassCastException
,如上例所示。更安全但更详细的替代方法是声明一个抽象方法,为每个子类返回适当的E
:
abstract class Edge<N extends Node<N, E>, E extends Edge<N, E>> {
public void m(N src) {
src.test(returnThis());
}
protected abstract E returnThis();
}
class EdgeImpl extends Edge<NodeImpl, EdgeImpl> {
@Override
protected EdgeImpl returnThis() {
return this;
}
}
抽象类边缘{
公共空间m(北src){
src.test(returnThis());
}
受保护的摘要E returnThis();
}
类EdgeImpl扩展了Edge{
@凌驾
受保护的EdgeImpl returnThis(){
归还这个;
}
}
您到底想实现什么目标?这个设计真的很奇怪。我想要一个由节点和边组成的图。我有不同类型的图(子类型),但是在一个子类型中使用的节点/边不应该在其他子类型中使用。
class EdgeImpl1 extends Edge<NodeImpl, EdgeImpl2> {}
src.test((E)this);
abstract class Edge<N extends Node<N, E>, E extends Edge<N, E>> {
public void m(N src) {
src.test(returnThis());
}
protected abstract E returnThis();
}
class EdgeImpl extends Edge<NodeImpl, EdgeImpl> {
@Override
protected EdgeImpl returnThis() {
return this;
}
}