Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用有界类型变量时参数不匹配_Java_Class_Generics_Types - Fatal编程技术网

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... } } 因此,其中一个

该守则已简化如下:

给定两个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...
    }
}
因此,其中一个上限节点被更改为原始类型。它进行编译,但给出了警告:

$ 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.java无法工作并输出此错误
  • 为什么要编译第二个Edge.java
  • 解决这个问题的最佳方法是什么
  • 为什么原始的Edge.java无法工作并输出此错误

    因为不能保证
    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;
        }
    }