一、分析

每个枚举都是java.lang.Enum的子类,都可以访问Enum类提供的方法,比如hashCode、name、valueOf等,其中valueOf方法会把一个String类型的名称转变成枚举项,也就是在枚举项中查找字面值和该参数相等的枚举项。

我们来深入分析一下该valueOf方法的源代码:

public static <T extends Enum<T>> T valueof(Class<T> enumType,String name){
//通过反射,从常量列表中查找
T result = enmuType.enumConstantDirector().get(name);
if(result != null)
return result;
if(name == null)
throw new NullPointerException("Name is null");
//最后排除无效参数异常
throw new IllegalArgumentException("No enum const" + enumType + "." + name);
}

valudOf方法通过反射从枚举类的常量声明中查找,若找到就直接返回,若找不到则抛出无效参数异常。valueOf的本意是保护编码的枚举安全性,使其不产生空枚举对象,简化枚举操作,但是却又引入了一个我们无法避免的IllegalArgumentException异常。

二、场景

我们来看如下代码:

public static void main(String[] args){
//注意summer是小写
List<String> params = Arrays.asList("Spring","summer");
for(String name:params){
//查找字面值与name相同的枚举项
Season s = Season.valueOf(name);
if(s != null){
//有枚举项时
System.out.println(s);
}else{
//没有枚举项
System.out.println("没有相关枚举项");
}
}
}

summer无法转换Season枚举,根据上面的分析,就会抛出IllegalArgumentException异常,一旦抛出异常,后续的代码就不运行了!!!

这与我们的习惯很不一致,例如我们从一个List中查找一个元素,即使不存在也不会报错,顶多返回indexOf方法返回-1。

三、建议

1.使用try-catch捕捉异常

try{
Season s = Season.valueOf(name);
//有该枚举项时处理
System.out.println("s");
}catch(Exception e){
System.out.println("无相关枚举项");
}

2.扩展枚举类

由于Enum类定义的方法都是final类型的,所以不希望被覆写,我们可以通过增加一个contains方法来判断是否包含指定的枚举项,然后在继续转换,代码如下:

enum Season{
Spring,Summer,Autumn,Winter; //是否包含枚举项
public static boolean contains(String name){
//所有的枚举值
Season[] season = values();
//遍历查找
for(Season s : season){
if(s.name().equals(name)){
return true;
}
} return false;
}
}

提高你的Java代码质量吧:使用valueof前必须进行校验的更多相关文章

  1. 提高你的Java代码质量吧:少用静态导入

    一.分析  从Java 5开始引入静态导入语法(import static),其目的是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序. 但是,滥用静态导入会使程序更难阅读,更难维护.静态导 ...

  2. 提高你的Java代码质量吧:推荐在复杂字符串操作中使用正则表达式

    一.分析  字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...

  3. 提高你的Java代码质量吧:如果有必要,使用变长数组吧

    一.分析  Java中的数组是定长的,一旦经过初始化声明就不可改变长度,这在实际使用中非常不方便. 二.场景  比如要对班级学生的信息进行统计,因为我们不知道一个班级会有多少学生(随时都有可能会有学生 ...

  4. 提高你的Java代码质量吧:小心switch带来的空值异常

    一.分析  使用枚举定义常量时,会有伴有大量的switch语句判断,目的是为每个枚举解释其行为. 我们知道,目前的Java的switch语句只能判断byte.short.char.int类型(JDK7 ...

  5. 提高你的Java代码质量吧:不要让类型默默转换

    一.分析  在Java运算中的类型转换,是先运算在进行类型转换的.具体场景如下. 二.场景  在如下程序中: public class Client{ public static final int ...

  6. 提高你的Java代码质量吧:谨慎包装类型的比较

    一.分析  基本类型可以比较大小,其所对应的包装类型都实现了Comparable接口此问题. 二.场景  代码如下: public class Client{ public static void m ...

  7. 提高你的Java代码质量吧:让我们疑惑的字符串拼接方式的选择

    一.分析  对于一个字符串进行拼接有三种方法:加号.concat方法.及StringBuiler或StringBuffer. 1."+"方法拼接字符串  str += " ...

  8. 提高你的Java代码质量吧:使用构造函数协助描述枚举项

    一.分析 一般来说,我们经常使用的枚举项只有一个属性,即排序号,其默认值是从0.1.2... ....但是除了排序号外,枚举还有一个(或多个)属性. 二.场景 比如,可以通过枚举构造函数声明业务值,定 ...

  9. 提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder

    一.建议  CharSequence接口有三个实现类与字符串相关:String.StringBuffer.StringBuilder,虽然它们都与字符串相关,但是其处理机制不同. 根据不同的场景,建议 ...

随机推荐

  1. 在C#调用C++的DLL方法(一)生成非托管dll

    C#与C/C++相比,前者的优势在于UI,后者的优势在于算法,C++下的指针虽然恶心,若使用得当还是相当方便的,最重要的问题是,市面上很多流行的开发工具库,几乎没有不支持C++的,但全面支持C#只能说 ...

  2. php-fpm 开启错误日志

    #php-fpm.conf #open catch_workers_output = yes #php.ini log_errors = On error_log=/data/logs/php-fpm ...

  3. Apache 编译扩展的方法

    下载源码包 进入源码包的modules目录 选择你要编译的.c文件 eg: /home/work/local/apache/bin/apxs -c -i -a mod_proxy_http.c 选项说 ...

  4. 一、富有表现力的JavaScript

    第一章:富有表现力的JavaScript 1.1  JavaScript的灵活性 1.2  弱类型语言 1.3  函数是一等对象 1.4  对象的易变性 1.5  继承 1.6  JavaScript ...

  5. 网络技术教程笔记(20)ISDN

    广域网与接入网技术 广域网与接入网技术 常见接入技术--ISDN 综合业务数字网(Integrated Services Digital Network,ISDN)由电话综合数字网IDN演化而成,能够 ...

  6. 十大最值得注意的MySQL变量

    MySQL数据库中的变量非常多,下文为您整理出了十大最值得注意的MySQL变量,希望对您学习MySQL数据库能够有一些帮助. AD: MySQL变量很多,其中有一些MySQL变量非常值得我们注意,下面 ...

  7. hdu 3518 Boring counting 后缀数组

    题目链接 根据height数组的性质分组计算. #include <iostream> #include <vector> #include <cstdio> #i ...

  8. java selenium webdriver实战 helloWord

    第一步:建立Maven项目 Selenium 支持 maven 工程,这会让你的工作更加简便. 用 Eclipse 建个 Maven 的工程,建成后,修改 pom.xml <dependenci ...

  9. windows中使用Git工具连接GitHub(配置篇)

    Git在源码管理领域目前占很大的比重了,而且开源的项目很多都转到GitHub上面了.例如:jQuery, reddit, Sparkle, curl, Ruby on Rails, node.js,  ...

  10. 转 C语言面试题大汇总

    转 C语言面试题大汇总,个人觉得还是比较全地!!! \主 题:   C语言面试题大汇总,个人觉得还是比较全地!!!  作 者:   free131 (白日?做梦!)   信 誉 值:   100    ...