Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.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_Generics - Fatal编程技术网

Java 如何调用泛型类型对象的方法?

Java 如何调用泛型类型对象的方法?,java,generics,Java,Generics,下面的代码给出了错误: SceneNode.java:17: cannot find symbol symbol : method execute() location: class java.lang.Object operation.execute(); ^ 1 error 代码: 我很确定,拥有一个SceneNode基类并为所有不同类型的节点建立子类将是一个更好的主意(我正在尝试泛型,只是最近才了解它们)

下面的代码给出了错误:

SceneNode.java:17: cannot find symbol
symbol  : method execute() location:
class java.lang.Object
                operation.execute();
                         ^ 1 error
代码:


我很确定,拥有一个
SceneNode
基类并为所有不同类型的节点建立子类将是一个更好的主意(我正在尝试泛型,只是最近才了解它们)。为什么这样不行?我肯定缺少了泛型的一些基本知识。

它不起作用,因为
t
可以是任何类型,而Java是静态类型的。编译器不知道您是否将尝试创建
场景节点
——那么
执行
会做什么

一种选择是创建适当的接口,例如

public interface Executable {
    void execute();
}
然后在
sceneode
中约束
T
以实现
可执行文件

public class SceneNode<T extends Executable> {
    ...
}
公共类场景节点{
...
}
(我觉得有点奇怪,
T
必须扩展
Executable
,而不是在源代码中实现它,但是
T
可能最终成为一个接口本身,所以我想这是有意义的。)


那么它应该可以正常工作。当然,如果你想要的话,可以让<代码>可执行文件< /代码>抽象的超类,甚至是(非最终)具体类,但是我一般都喜欢使用接口,除非我有理由不这样做。

< P>我猜你来自C++背景。 编译器不知道T可能是什么类型的东西,因为您没有告诉它

例如,如果您有一个名为
Executable
的接口,它定义了
execute()
方法,那么您需要执行以下操作:

public class SceneNode<T extends Executable> {
    // ... 
}
公共类场景节点{
// ... 
}

现在,编译器将知道T是一个
可执行文件
,并将允许您访问该接口上的所有方法。

Java是静态类型语言。为了能够调用方法,您必须在编译时知道类型。您可以使用定义
execute()
方法的接口
execute
,而不是子类
T
(没有任何
)只有
java.lang.Object

定义的方法。最近,我遇到了一种情况,我必须在泛型对象上调用一个方法。让反思付诸行动对我来说很有效

public class SceneNode<T>{
    T operation;    
    public SceneNode() {
    }   
    public SceneNode(T operation) {
        this.operation = operation;
    }
    public void setOperation(T operation) {
        this.operation = operation;
    }
    public void doOperation() {
        Method m = operation.getClass().getMethod("execute");
        m.invoke(operation);
    }
}
公共类场景节点{
T操作;
公共场景节点(){
}   
公共场景节点(T操作){
这个操作=操作;
}
公共无效设置操作(T操作){
这个操作=操作;
}
公共无效操作(){
方法m=operation.getClass().getMethod(“执行”);
m、 调用(操作);
}
}

因为泛型实际上是Java的
对象(与相同),所以在指定基类之前,这就解决了,我现在也明白了原因。我以前见过这种语法,但我认为它的意思是“对象必须是这个对象的子类”。Callum:这意味着“参数类型必须是给定类型的子类型”,因此现在只能使用可执行文件的Type类型。我来自C++,实际上也很难得到,所以谢谢这个解释。这有点奇怪,我猜想编译器应该寻找一个泛型类的用法,看看是否有一个方法被调用,实际上是在C++中完成的。必须指定一个T扩展的类会降低泛型类的可用性,它不再是泛型的-它只适用于扩展这个类的对象,对吗?不管怎样,我想我需要进一步研究这个话题。@dty:是的,我已经开始研究了。我觉得很奇怪,但Java泛型就是这样:(对不起,为什么它不是实现可执行的?@LukAron:因为这不是泛型类型边界所使用的语法。看。我知道这有点奇怪,但它确实使它保持一致。
public class SceneNode<T extends Executable> {
    // ... 
}
public class SceneNode<T>{
    T operation;    
    public SceneNode() {
    }   
    public SceneNode(T operation) {
        this.operation = operation;
    }
    public void setOperation(T operation) {
        this.operation = operation;
    }
    public void doOperation() {
        Method m = operation.getClass().getMethod("execute");
        m.invoke(operation);
    }
}