今天就跟大家聊聊有java中关一些不为人知的枚举,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
枚举在java里也算个老生长谈的内容了,每当遇到一组需要类举的数据时我们都会自然而然地使用枚举类型:
//我们不仅想用英语的方位,同时还想取得对应的本地化名称(这里是中文) enum方向{ 东(“东“), 西(“西“), 北(“北“), 南(“南“); 私人最终字符串名称;//注意是私有的 私人方向(字符串名称){ this.name=名称; } 公共字符串getName () { 返回this.name; } } 公共类测试{ 公共静态void main (String [] args) { (var v: Direction.values ()) { System.out.println (v.toString() +“——祝辞;“+ v.getName ()); } } }
编译并运行程序,你将会得到下面这样的结果:
东——在东
引用>
西——在西
北——在北
南——在南很多教程到此就结束了,点到为止,对于枚举值后面的圆括号有什么作用,为什么构造函数需要私人修饰都一笔带过甚至连解释说明都没给出。然而理解这些却是我们进一步学习枚举的高阶用法的前提。
不过没关系,我们可以自己动手一探究竟,比如看看反编译后的代码,从编译器处理枚举类型的方法中一探究竟。这里我们将会利用jad,具体的使用教程参考园内其他优秀文章,本文不进行赘述,我们直接看反编译后的结果:
最终扩展枚举类方向 {/*省略部分无关紧要的方法*/私人方向(字符串,整数,字符串s1) { 超级(年代,我);=s1名称; } 公共字符串getName()//这是我们自定义的getter { 返回名称; } 公共静态最终方向东; 西方公共静态最终方向; 公共静态最终方向北; 公共静态最终方向南; 私人最终字符串名称;//省略不重要的部分字段 静态 { 东=新方向(“EAST" 0“\ u4E1C"); 西方=新方向(“WEST" 1“\ u897F"); 北=新方向(“NORTH" 2“\ u5317"); 南=新方向(“SOUTH" 3“\ u5357");//省略部分字段的初始化 } }首先看到我们的枚举是一个类,其次它继承自java.lang.Enum(这意味着enum是无法显式指定基类的),而我们在方向的构造函数中调用了其父类的构造函数,通过阅读文档可知,java.lang.Enum的构造函数是保护修饰的,也就是说对于java。朗包以外的使用者无法调用这个构造函数。同时文档也指出,该构造函数是由编译器自动调用的。因此我们自己定义的enum的构造函数也是无法正常调用的,只能由编译器用来初始化enum的枚举成员。既然本身无法被用户调用那么java干脆直接不允许保护和公共(默认和私人允许)修饰自定义enum类型的构造函数以免造成误用。
另外我们的自定义构造函数其实是被编译器进行了合成,除了自定义参数之外还有枚举成员的字符串名称以及一个从0开始的序号(可用序数方法获取),前两个参数编译器会自动为我们添加,而自定义参数则是根据在我们给定的枚举成员后的圆括号里的值传递给构造函数,简单说就是:
东(“东“), 西(“西“), 北(“北“), 南(“南“);//转换为(unicode字符被转码) 东=新方向(“EAST" 0“\ u4E1C"); 西方=新方向(“WEST" 1“\ u897F"); 北=新方向(“NORTH" 2“\ u5317"); 南=新方向(“SOUTH" 3“\ u5357");如果我需要更多字段,只需要像这样:
java中一些不为人知的枚举