簡體   English   中英

如何調用泛型類型對象的方法?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM