如何让Java枚举像Kotlin枚举一样显示自定义value而非name?
问题描述
我刚接触Java和Kotlin枚举。
在Java 9+中,编写如下代码:
enum Animal { DOG("woof"), CAT("meow"); public String sound; Animal(String sound) { this.sound = sound; } } class Foo { public static void main(String[] args) { List<Animal> foo = List.of(Animal.DOG, Animal.CAT); System.out.println(Animal.values()); }
在IntelliJ IDEA调试器中设置断点查看时,每个枚举元素以自身name(如{Animal@448} "DOG")标识,而非自定义的sound值。调试信息如下:
foo = {ImmutableCollections$List12@444} size =2 0 = {Animal@448} "DOG" sound = "woof" name = "DOG" ordinal = 0 1 = {Animal@449} "CAT" sound = "meow" name = "CAT" ordinal = 1
但使用Kotlin编写的okhttp.Protocol枚举时,调试器显示的是自定义的protocol值而非name:
import okhttp3.Protocol; class Foo { public static void main(String[] args) { List<Protocol> foo = List.of(Protocol.HTTP_1_0, Protocol.HTTP_1_1); System.out.println(Animal.values()); }
对应调试信息如下:
foo = {ImmutableCollections$List12@562} size =2 0 = {Protocol@566} http/1.0 protocol = "http/1.0" name = "HTTP_1_0" ordinal = 0 1 = {Protocol@567} http/1.1 protocol = "http/1.1" name = "HTTP_1_1" ordinal = 1 }
相关Kotlin枚举主构造如下:
enum class Protocol(private val protocol: String) { /** * An obsolete plaintext framing that does not use persistent sockets by default. */ HTTP_1_0("http/1.0"),
现询问:如何让Java枚举实现类似Kotlin的效果,在调试时显示自定义value而非name?
解决方案
要让Java枚举在IntelliJ IDEA调试器中显示自定义值而非默认的name,只需要重写枚举的toString()方法,返回你想展示的自定义属性即可。
修改后的Java枚举代码示例:
enum Animal { DOG("woof"), CAT("meow"); public String sound; Animal(String sound) { this.sound = sound; } // 重写toString方法,返回自定义的sound值 @Override public String toString() { return sound; } }
修改后,在IntelliJ调试器中查看枚举元素时,就会显示sound属性的值(比如{Animal@xxx} "woof"),和Kotlin Protocol枚举的展示效果一致。
原理是:IntelliJ IDEA调试器默认会使用对象的toString()方法返回值来展示对象标识信息。Java枚举默认的toString()方法返回枚举的name()值,而你看到的Kotlin Protocol枚举已经隐式或显式重写了toString(),返回了自定义的protocol属性值,因此调试器会展示自定义内容。
内容的提问来源于stack exchange,提问作者mellow-yellow
相关产品推荐
相关产品推荐

