开发背景:
在开发过程中遇到需要通过给定的值来获取对应的枚举值,如下例枚举类中,需要通过传入"春"来获取SPRING。
public
开始尝试通过Enum的内置方法valueOf()获取,使用报错:
public
输出:
Exception
我们打开valueOf源码看看他是通过什么值获取,
方法注释
需要通过与声明枚举类型的标识完全匹配,就是说我要通过"SPRING"字符串来获取SPRING枚举类,但我需要的是通过“春”来获取到SPRING。
后来我想到一种实现方法,通过获取枚举类的构造方法,然后反射执行其构造方法来获取。先显示的通过反射看看Season的构造方法长什么样子。
public
???,小朋友头上多了好多问号,明明我的构造函数只有java.lang.String类型,为什么变成了三个参数了。
于是,我在Season中新增了一个无参构造,再次运行上述代码。
输出
发现无参构造默认加了两个参数,我们打开抽象类Enum看看,发现里面存在下列构造方法,且通过注释可以得知,程序员无需调用此构造方法,当声明枚举类时编译器会自动实现该方法,而参数name、ordinal分别是“与声明枚举类型标识完全匹配的字符串”和“枚举声明在枚举类中的序号,从0开始”。
/**
所以我需要通过传入name、ordinal、和自定义的值("春")来获取对应的SPRING。但是我可能不知道其name和ordinal。或者当我知道其name的情况下,我直接使用valueOf(name)直接就可以获取相关的枚举值了。所有此类方法行不通,而且Class类中的newInstance方法有这么一段代码,就是说如果通过newInstance来反射获取枚举类型的对象将抛出IllegalArgumentException异常。我们用代码试验一下:
newInstance源码
public
奇怪的知识又多了。这个时候我想到通过利用我在上篇文章中的方法获取。链接在下方:
远方的大猪:枚举工具类-反射获取枚举类中变量的所有值zhuanlan.zhihu.com非反射代码实现如下,可以更好的理解设计思路:(需要在枚举类Season类中添加getSeason()方法)
public
对应的反射实现的工具类如下:
public
-----------------------------------------------------------------------------------------------
输出
注:上述好多基本方法在文章
远方的大猪:枚举工具类-反射获取枚举类中变量的所有值zhuanlan.zhihu.com中已详细说明,此处不冗余讲述,如有不清楚的地方可留言。也请大佬指出不足之处。
总结:
通过上述工具类的开发,触及到了好多知识盲区,不过正是这样也拓展了知识,同时加深了对知识点的理解。
当然在使用反射工具类时也有一些弊端,如需要=抛出比较多的异常。还有,上述工具类只能针对一个自定义的值,当存在多个自定义值时将不能实现。
这里我想到了一种实现方式,能够解决这种多值问题,但只针对多个自定义值的类型不一样的情况,如一个值类型时String,一个是int,这样可以通过类型获取到指定的值。但如果存在两个自定义的值都是String类型时,将无法通过反射知道两个String将如何分配,这里我没有想到好的方式解决。
由于时间关系,类型不同的多值实现将在下次更新。