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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:35:30  来源:igfitidea点击:

How do I call a method of a generic type object?

javagenerics

提问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 operationthat's type is defined by the Tclass variables. This way I can pass a Transformation/ Model/ Switchobject (that has an executemethod) 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 SceneNodeand 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 Tcould be anytype, and Java is statically typed. The compiler has no idea whether you'll try to create a SceneNode<String>- then what would executedo?

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

One option is to create an appropriate interface, e.g.

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

public interface Executable {
    void execute();
}

and then to constrain Tin SceneNodeto implement Executable:

然后限制TSceneNode实施Executable

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

(I find it a little bit odd that Thas to extendExecutablerather than implementit in the source code, but then Tcould end up being an interface itself, so I guess it makes sense.)

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

Then it should work fine. Of course you couldmake Executablean 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, Executablewhich 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 Executablethat 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