簡體   English   中英

如何調用正確返回泛型類型的方法(Java)?

[英]How to call a method returning generic type correctly (Java)?

我有一個泛型方法,它具有要返回的泛型類型。 我想正確調用它以返回編譯錯誤,以防我使用它的返回類型不符合邊界,從而避免運行時錯誤(與編譯)並使用 Java 泛型類型的所有功能。

public <T extends IDeserializable> T restoreObject(byte[] objectArray) {

    T object = T.getDeserialized(objectArray);
    
    return object;
}

然而,這樣稱呼它

File ret = restoreObject(new byte[] {1,2,3});

不會產生編譯錯誤,因此只會在運行時產生錯誤。 File 類型沒有實現 IDeserializable,但是 java 不會產生編譯錯誤。

public interface IDeserializable {
        public static <T> T getDeserialized(byte[] data) {
            return null;
        }
}

這里有幾個問題:

  • 對類型參數調用靜態方法並不像您認為的那樣工作( 是一個關於的問題)。
  • 無論如何, getDeserialized是一個實例方法,而不是靜態方法,所以你不能做T.getDeserialized(objectArray)
  • 編譯器不能像那樣推斷T @luk2302 糾正了我 - T將被推斷為您將結果分配給的任何類型。

您需要為restoreObject一個類型為T的參數,以便編譯器可以推斷出T並且您可以調用getDeserialized方法:

public <T extends IDeserializable> T restoreObject(byte[] objectArray, T t) {
    return t.getDeserialized(objectArray);
}

但是,我懷疑您的意思是getDeserialized是一個靜態方法。 不幸的是,您不能這樣做,因為靜態方法不會被覆蓋。 但是,您可以使restoreObject帶一個Function參數:

public <T extends IDeserializable> T restoreObject(byte[] objectArray, Function<byte[], T> deserialize) {
    return deserialize.apply(objectArray);
}

然后,您可以對deserialize參數使用 lambda 或方法引用。


您也可以使用Serializable ,但@daniu 指出Serializable將在未來一段時間內被刪除,這不是一個好主意。 已經有大量的庫,因此您不必自己處理序列化/反序列化。 以下是 Java 中序列化的一些替代方案。 如果您不想使用外部庫,Java 也有自己的 XML API。

如果你能想象一個理論類型的Weirdo可以做到:

 class Weird extends File implements IDeserializable

進而:

static <T> T getDeserialized(byte[] data) {
        return new Weirdo();
}

或者更簡單(因為不能強制轉換為類型參數):

 static <T> T getDeserialized(byte[] data) {
      return (T) "";
 }

您可以看到問題出在您的getDeserialized開始時,調用者必須信任您。 但是,如果您認為接口中存在靜態方法的原因(它們的主要目的是返回接口的實例),那么您就是在濫用這些方法。 如果沒有人可以覆蓋它,那么將其static有什么意義? 您可能想要重新考慮您正在嘗試做什么。

但無論如何,如果你用一個class替換它 - 你得到一個編譯時錯誤(不過我會讓你弄清楚原因):

public static class IDeserializable {

    static <T> T getDeserialized(byte[] data) {
        return ...;
    }
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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