[英]How do I call a method of a generic type object?
下面的代码给了我错误:
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();
}
}
这是一个简单场景图的缩减(为了您的可读性)开始。 节点可以是模型、转换、开关等,所以我创建了一个名为operation
的变量,它的类型由T
类变量定义。 这样我就可以传递一个Transformation
/ Model
/ Switch
对象(它有一个execute
方法)并像这样传递它:
SceneNode<Transformation> = new SceneNode<Transformation>(myTransformation);
我很确定有一个SceneNode
基类和所有各种类型节点的子类会是一个更好的主意(我正在尝试泛型,最近才了解它们)。 为什么这不起作用? 我一定遗漏了一些关于泛型的基本知识。
它不起作用,因为T
可以是任何类型,而 Java 是静态类型的。 编译器不知道您是否会尝试创建SceneNode<String>
- 那么会execute
什么?
一种选择是创建一个适当的界面,例如
public interface Executable {
void execute();
}
然后在SceneNode
约束T
以实现Executable
:
public class SceneNode<T extends Executable> {
...
}
(我觉得T
必须扩展Executable
而不是在源代码中实现它有点奇怪,但是T
最终可能会成为一个接口本身,所以我想这是有道理的。)
那么它应该可以正常工作。 当然,如果您愿意,您可以使Executable
成为抽象超类 - 甚至是(非最终)具体类 - 但我通常更喜欢使用接口,除非我有理由不这样做。
我猜你来自 C++ 背景。
编译器不知道 T 可能是什么东西,因为你没有告诉它。
例如,如果您有一个名为Executable
的接口,它定义了您的execute()
方法,那么您需要执行以下操作:
public class SceneNode<T extends Executable> {
// ...
}
现在,编译器会知道 T 是一个Executable
,并且会让您访问该接口上的所有方法。
Java 是静态类型语言。 您必须在编译时知道类型才能调用方法。 您可以使用定义execute()
方法的接口Executable
来代替子类。 T
(没有任何<T extends SomeClass>
)只有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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.