簡體   English   中英

Enum.valueOf 為擴展 Enum 的未知類型的 class 引發警告?

[英]Enum.valueOf throws a warning for unknown type of class that extends Enum?

給這個:

Class<? extends Enum> enumClass = ...; // being passed in from a constructor
Enum e = Enum.valueOf(enumClass, aString); // produces a warning that looks like

[unchecked] unchecked method invocation: valueOf(java.lang.Class,java.lang.String) in java.lang.Enum is applied to (java.lang.Class,java.lang.String)

我不想使用 generics 因為這是一個重大變化。 我不想壓抑。 我不明白為什么會發生此警告。 我想這是因為無法擴展 Enum 類型。 我明白了。 但我不明白為什么通配符 class 會拋出這個奇怪的錯誤。 有沒有辦法在不使用@SupressWarning或使用 generics 的情況下解決這個問題?

編輯:為了澄清,使用 generics 的以下代碼使警告 go 消失。

class Foo<T extends Enum<T>>{
    Class<T> enumClass;
    Enum e = Enum.valueOf(enumClass, aString);
}

<T>的用法就是我使用 generics 的意思。 我不能這樣做,因為這將是一個巨大的級聯變化。

EnumClass都是通用的。 因此,如果您不想要任何警告:

class Foo<T extends Enum<T>>{
    Class<T> enumClass;
    T e = Enum.valueOf(enumClass, str);
}

或者你可以有一個通用的方法:

public <T extends Enum<T>> T getEnumValue(Class<T> clazz, String name) {
    T e = Enum.valueOf(clazz, name);
    return e;
}

但是,如果您不使用 generics,那么您使用的是原始類型,因此編譯器會發出警告 - 除了抑制它們之外別無選擇。

這似乎是一個編譯器錯誤 - 它應該是一個錯誤,而不是一個警告。

在編譯方法調用表達式Enum.valueOf(enumClass...)時,首先將捕獲轉換應用於參數類型。

<W extends Enum> // a new type parameter 
Class<W> enumClass; // the type of the argument after capture conversion

然后,對Enum.<T>valueOf(enumClass...)進行類型推斷,結果為T=W

然后,檢查替換后T的邊界,即W是否是Enum<W>的子類型。

(這個過程對於 15.12.2.2 和 15.12.2.3 是相同的;並且 15.12.2.7 肯定會產生 T=W)

在這里,檢查應該失敗。 所有編譯器都知道WEnum的子類型,它不能推斷WEnum<W>的子類型。 (好吧,我們知道這是真的,除了W=Enum ;但是這個知識在子類型規則中不存在,所以編譯器不使用它 - 我們可以通過使用MyEnum層次結構來驗證這個示例,編譯器的行為將相同.)

那么為什么編譯器只通過一個警告就通過了邊界檢查呢? 還有另一條規則允許從Raw分配到Raw<X>並帶有未經檢查的警告。 為什么允許這樣做是另一個問題(不應該如此),但編譯器確實感覺到Raw可以分配給Raw<X> 顯然,這條規則被錯誤地混入了上述子類型檢查步驟,編譯器認為由於WEnum ,它也是一個Enum<W> ,編譯器通過子類型檢查只是一個警告,違反了規范。

如果這樣的方法調用不應該編譯,那么正確的方法是什么? 我看不到任何 - 只要參數enumClass的類型還不是Class<X extends Enum<X>>的遞歸形式,沒有任何類型的轉換/轉換可以使其成為該形式,因此有無法匹配Enum.valueOf方法的簽名。 也許javac家伙故意違反規范只是為了讓這種代碼編譯!

如果您考慮一下 valueOf 內部必須發生的事情,您會意識到您的代碼不可能像編寫的那樣工作。 Enum.valueOf 需要一個實際枚舉 class 的實例作為參數; 然后它簡單地遍歷該 class 的values()以尋找匹配項。

由於type erasure , generics 在您的代碼中不起作用。 沒有實際類型被傳遞到Enum.valueOf

暫無
暫無

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

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