java 如何调用泛型类型对象的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5129685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I call a method of a generic type object?
提问by Callum
The below code gives me the error:
下面的代码给了我错误:
SceneNode.java:17: cannot find symbol
symbol : method execute() location:
class java.lang.Object
operation.execute();
^ 1 error
Code:
代码:
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();
}
}
It's a cut down (for your readability) start of a simple scene graph. The node could be a model, transformation, switch, etc., so I made a variable called operation
that's type is defined by the T
class variables. This way I can pass a Transformation
/ Model
/ Switch
object (that has an execute
method) and pass it like this:
这是一个简单场景图的缩减(为了您的可读性)开始。节点可以是模型、转换、开关等,所以我创建了一个名为operation
该类型的T
变量,该变量由类变量定义。这样我可以通过一个Transformation
/ Model
/Switch
对象(即具有一个execute
方法),并通过它是这样的:
SceneNode<Transformation> = new SceneNode<Transformation>(myTransformation);
I'm pretty sure having a base class of SceneNode
and subclassing for all the various types of nodes would be a better idea (I was trying out generics, only learnt about them recently). Why doesn't this work? I must be missing something fundamental about generics.
我很确定SceneNode
为所有各种类型的节点建立一个基类和子类将是一个更好的主意(我正在尝试泛型,最近才了解它们)。为什么这不起作用?我一定遗漏了一些关于泛型的基本知识。
回答by Jon Skeet
It doesn't work because T
could be anytype, and Java is statically typed. The compiler has no idea whether you'll try to create a SceneNode<String>
- then what would execute
do?
它不起作用,因为T
可以是任何类型,而 Java 是静态类型的。编译器不知道您是否会尝试创建一个SceneNode<String>
- 那么怎么execute
办?
One option is to create an appropriate interface, e.g.
一种选择是创建一个适当的界面,例如
public interface Executable {
void execute();
}
and then to constrain T
in SceneNode
to implement Executable
:
然后限制T
在SceneNode
实施Executable
:
public class SceneNode<T extends Executable> {
...
}
(I find it a little bit odd that T
has to extendExecutable
rather than implementit in the source code, but then T
could end up being an interface itself, so I guess it makes sense.)
(我发现它T
必须扩展Executable
而不是在源代码中实现它有点奇怪,但T
最终可能会成为一个接口本身,所以我想这是有道理的。)
Then it should work fine. Of course you couldmake Executable
an abstract superclass instead - or even a (non-final) concrete class - if you wanted, but I would generally prefer to use an interface unless I had some reason not to.
那么它应该可以正常工作。当然,如果你愿意,你可以创建Executable
一个抽象的超类——或者甚至是一个(非最终的)具体类——但我通常更喜欢使用接口,除非我有一些理由不这样做。
回答by dty
I'm guessing you come from a C++ background.
我猜你来自 C++ 背景。
The compiler has no idea what kind of a thing T might be because you haven't told it.
编译器不知道 T 可能是什么东西,因为你没有告诉它。
If you had an interface called, for example, Executable
which defines your execute()
method, then you would need to do:
例如,如果您调用了一个接口Executable
来定义您的execute()
方法,那么您需要执行以下操作:
public class SceneNode<T extends Executable> {
// ...
}
Now, the compiler will know that T is an Executable
, and will give you access to all the methods on that interface.
现在,编译器会知道 T 是一个Executable
,并且会让您访问该接口上的所有方法。
回答by Bozho
Java is statically typed language. You must know the type at compile-time in order to be able to invoke a method. Instead of a subclass you can have an interface Executable
that defines the execute()
method. T
(without any <T extends SomeClass>
) has only the methods defined by java.lang.Object
.
Java 是静态类型语言。您必须在编译时知道类型才能调用方法。您可以拥有一个Executable
定义execute()
方法的接口,而不是子类。T
(没有任何<T extends SomeClass>
)只有由 定义的方法java.lang.Object
。