檢查物件的類型是否為枚舉
1. 概述
當我們使用 Java 時,理解和操作物件類型是基本技能。一個常見的挑戰是檢查物件是否屬於Enum
類型。
在本快速教程中,我們將探索確定物件類型是否為enum.
2.問題介紹
枚舉類型或enum
,
提供了一種強大的方法來表示不同類型中的一組固定值。動態確認物件是否屬於enum
類型對於編寫健全且類型安全的程式碼至關重要。
例如,我們有一個簡單的enum
:
enum Device {
Keyboard, Monitor, Mouse, Printer
}
現在,假設我們有一個物件:
Object obj = Device.Keyboard;
正如我們所看到的, obj
是在Object.
我們的挑戰是檢查它的類型是否是enum.
在本教程中,我們將學習解決此問題的不同方法。此外,我們將使用單元測試斷言來驗證結果。
3.使用instanceof
運算符
我們知道所有枚舉都有相同的超類別: java.lang.Enum
。 instanceof
運算子允許我們測試一個物件是否是特定類別或介面的實例。
因此,我們可以利用這個運算子來檢查一個物件是否是Enum
類型:
Object obj = Device.Keyboard;
assertTrue(obj instanceof Enum);
4.使用Enum.class.isInstance()
方法
Class.isInstance()
方法與instanceof
運算子的作用相同。由於我們要檢查Enum
類型, Enum.class.isInstance(obj)
解決了這個問題:
Object obj = Device.Keyboard;
assertTrue(Enum.class.isInstance(obj));
5.使用Enum.class.isAssignableFrom()
方法
與Class.isInstance()
方法類似, Class.isAssignableFrom()
方法檢查左邊的類別是否與給定Class
參數相同或超類型。這兩種方法略有不同。但是,如果我們使用它們來解決我們的問題,那沒有什麼區別:
Object obj = Device.Keyboard;
assertTrue(Enum.class.isAssignableFrom(obj.getClass()));
6. Class.isEnum()
方法
另一種確定類別是否表示enum
方法是使用Class
類別提供的isEnum()
方法:
Object obj = Device.Keyboard;
assertTrue(obj.getClass().isEnum());
這種方法非常簡單。但是,它可能無法檢查某些枚舉實例。接下來,讓我們仔細看看Class.isEnum()
的陷阱。
7. Class.isEnum()
陷阱: Enum
主體的枚舉實例
我們知道枚舉可以有自訂方法。此外,枚舉實例可以覆寫這些方法。接下來,讓我們來看另一個枚舉範例:
enum Weekday {
Monday, Tuesday, Wednesday, Thursday, Friday,
Saturday {
@Override
boolean isWeekend() {
return true;
}
},
Sunday {
@Override
boolean isWeekend() {
return true;
}
};
boolean isWeekend() {
return false;
}
}
如上面的程式碼所示, Weekday
有isWeekend()
方法。預設情況下,該方法傳回false
。但是, Saturday
和Sunday
實例已重寫此方法以傳回true
。
接下來,我們用學到的解決方案來驗證一些Weekday
實例,看看它們是否能夠報告正確的結果。首先,我們以Monday
:
Object monday = Weekday.Monday;
assertTrue(monday instanceof Enum);
assertTrue(Enum.class.isInstance(monday));
assertTrue(Enum.class.isAssignableFrom(monday.getClass()));
assertTrue(monday.getClass().isEnum());
如果我們執行測試,所有四種方法都會按預期工作。接下來,我們將Sunday
實例作為輸入並重複測試:
Object sunday = Weekday.Sunday;
assertTrue(sunday instanceof Enum);
assertTrue(Enum.class.isInstance(sunday));
assertTrue(Enum.class.isAssignableFrom(sunday.getClass()));
assertFalse(sunday.getClass().isEnum()); // <-- isEnum() check failed when Enum values with body
這次, Class.isEnum()
不會產生正確的答案。接下來我們就來了解為什麼會出現這樣的情況。
當單一枚舉實例重寫方法時(例如我們範例中的Saturday
和Sunday
,將建立一個充當枚舉子類別的匿名類別。在這種情況下, Sunday.getClass()
傳回匿名子類別而不是Weekday
類別。因此,在類別上呼叫isEnum()
會產生false.
因此,我們不應該將Class.isEnum()
方法視為此問題的可靠解決方案。
八、結論
確定物件的類型是否為enum
對於編寫靈活且健壯的 Java 程式碼至關重要。在本文中,我們探討了執行檢查的不同方法:
-
instanceof
操作符 -
Enum.class.isInstance()
方法 -
Enum.class.isAssignableFrom()
方法
此外,我們強調了enumValue.getClass().isEnum()
檢查的潛在陷阱,強調在處理枚舉實例中的重寫方法時其可靠性會降低。因此,我們不應該依賴這種方法作為最終的解決方案。
與往常一樣,範例的完整原始程式碼可在 GitHub 上取得。