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

2022-09-04 01:12:21

下面的代码给了我一个错误:

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

法典:

import java.util.LinkedList;
import java.util.Iterator;

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() {
        operation.execute();
    }
}

这是一个简单的场景图的削减(为了您的可读性)。开始。节点可以是模型、转换、开关等,所以我做了一个名为“类型”的变量,该类型由类变量定义。通过这种方式,我可以传递一个 / / 对象(有一个方法)并像这样传递它:operationTTransformationModelSwitchexecute

SceneNode<Transformation> = new SceneNode<Transformation>(myTransformation);

我很确定为所有各种类型的节点提供一个基类和子类化将是一个更好的主意(我正在尝试泛型,最近才了解它们)。为什么这不起作用?我一定错过了一些关于泛型的基本知识。SceneNode


答案 1

它不起作用,因为可以是任何类型,并且Java是静态类型的。编译器不知道你是否会尝试创建一个 - 那么该怎么办?TSceneNode<String>execute

一种选择是创建适当的界面,例如

public interface Executable {
    void execute();
}

然后约束在实现:TSceneNodeExecutable

public class SceneNode<T extends Executable> {
    ...
}

(我发现它必须扩展而不是在源代码中实现它,但这有点奇怪,但最终可能成为一个接口本身,所以我想这是有道理的。TExecutableT

然后它应该工作正常。当然,如果你愿意,你可以创建一个抽象的超类 - 甚至是一个(非最终的)具体类 - 但我通常更喜欢使用接口,除非我有一些理由不这样做。Executable


答案 2

我猜你来自C++背景。

编译器不知道T可能是什么样的东西,因为你还没有告诉它。

例如,如果你有一个接口,它定义了你的方法,那么你将需要这样做:Executableexecute()

public class SceneNode<T extends Executable> {
    // ... 
}

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


推荐