使用valueOf前必須進行校驗

每個枚舉都是java.lang.Enum的子類,都可以訪問Enum類提供的方法,比如hashCode(),name(),valueOf()等.....

其中valueOf()方法會把一個String類型的名稱轉變為枚舉項,也就是枚舉項中查找出字面值與該參數相等的枚舉項,雖然這個方法很簡單,但是JDK卻做了一個對于開發人員來說并不簡單的處理:

看代碼:

復制代碼
 1 import java.util.Arrays;
 2 import java.util.List;
 3 
 4 public class Client {
 5     public static void main(String[] args) {
 6         //注意summer是小寫
 7         List<String> params = Arrays.asList("Spring", "summer");
 8         for (String name : params) {
 9             //查找表面值與name相同的枚舉項
10             Season s = Season.valueOf(name);
11             if (s != null) {
12                 // 有該枚舉項時的處理
13                 System.out.println(s);
14             } else {
15                 // 沒有該枚舉項時的邏輯處理
16                 System.out.println("無相關枚舉項");
17             }
18         }
19         
20     }
21 
22 }
23 
24 enum Season {
25     Spring, Summer, Autumn, Winter;
26 }
復制代碼

運行輸出:

復制代碼
Spring
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant cn.summerchill.test.Season.summerat java.lang.Enum.valueOf(Unknown Source)at cn.summerchill.test.Season.valueOf(Client.java:1)at cn.summerchill.test.Client.main(Client.java:12)
復制代碼

這段代碼看起來很完美了,其中考慮到從String轉換成枚舉類型可能不成功的情況,比如沒有匹配到指定的值,此時valueof的返回值應該為空,所以后面又緊跟著if....else判斷輸出.

但是運行結果拋出異常.報告是無效參數異常...也就說summer(小寫s)午飯轉換為Season枚舉,無法轉換那也不應該拋出IllegalArgumentException異常啊,一旦拋出這個異常,后續的代碼就不能執行了,這才是要命的,

這與我們的習慣用法不一致,例如我們從List中查找一個元素,即使不存在也不會報錯,頂多indexOf方法返回-1.

看源碼:

復制代碼
 1     public static <T extends Enum<T>> T valueOf(Class<T> enumType,
 2                                                 String name) {
 3         T result = enumType.enumConstantDirectory().get(name);//通過反射,從常量列表中查找.
 4         if (result != null)
 5             return result;
 6         if (name == null)
 7             throw new NullPointerException("Name is null");
 8         throw new IllegalArgumentException(//最后報無效參數異常
 9             "No enum constant " + enumType.getCanonicalName() + "." + name);
10     }
復制代碼

valueOf方法先通過反射從枚舉類的常量聲明中查找,若找到就直接返回,若找不到就拋出無效參數異常.

valueOf方法本意是保護編碼中的枚舉安全性,使其不產生空枚舉對象,簡化枚舉操作,但是又引入了一個我們無法避免的IllegalArgumentException異常.

可能有讀者會所此處valueOf()方法的源代碼不對,以上源代碼是要輸入兩個參數,而我們的Season.valueOf()值傳遞一個String類型的參數.

真的是這樣嗎?是的,因為valueOf(String name)方法是不可見的,是JVM內置的方法,我們只有通過閱讀公開的valueOf方法來了解其運行原理.

在Season枚舉類中引用valueOf方法有三個:

但是在Enum的源碼中只有一個valueOf()的方法: 其他兩個方法都是JVM的內置方法...

問題清楚了,我們有兩種方式可以解決處理此問題:

(1)使用try....catch捕獲異常

復制代碼
            try {Season s = Season.valueOf(name);// 有該枚舉項時的處理
                System.out.println(s);} catch (Exception e) {System.out.println("無相關枚舉項");}
復制代碼

?

(2)擴展枚舉類:

由于Enum類定義的方法基本上都是final類型的,所以不希望被覆寫,那我們可以學習List和String,通過增加一個contains方法來判斷是否包含指定的枚舉項,然后再繼續轉換,看代碼:

復制代碼
 1 enum Season {
 2     Spring, Summer, Autumn, Winter;
 3     public boolean contains(String _name){
 4         Season[] season = values();
 5         for(Season s:season){
 6             if(s.name().equals(_name)){
 7                 return true;
 8             }
 9         }
10         return false;
11         
12     }
13 }
復制代碼

?

?Season枚舉具備了靜態方法contains()之后,就可以在valueOf前判斷一下是否包含指定的枚舉名稱了,若包含則可以通過valueOf轉換為Season枚舉,若不包含則不轉換.

總結代碼:

復制代碼
 1 import java.util.Arrays;
 2 import java.util.List;
 3 
 4 public class Client {
 5     public static void main(String[] args) {
 6         // 注意summer是小寫
 7         List<String> params = Arrays.asList("Spring", "summer");
 8         for (String name : params) {
 9             // 查找表面值與name相同的枚舉項
10 //            Season s = Season.valueOf(name);
11 //            if (s != null) {
12 //                // 有該枚舉項時的處理
13 //                System.out.println(s);
14 //            } else {
15 //                // 沒有該枚舉項時的邏輯處理
16 //                System.out.println("無相關枚舉項");
17 //            }
18             if (Season.contains(name)) {
19                 Season s = Season.valueOf(name);
20                 // 有該枚舉項時的處理
21                 System.out.println(s);
22             } else {
23 
24                 System.out.println("無相關枚舉項");
25 
26             }
27 
28         }
29 
30     }
31 
32 }
33 
34 enum Season {
35     Spring, Summer, Autumn, Winter;
36 
37     // 是否包含指定名稱的枚舉項
38     public static boolean contains(String name) {
39         // 所有的枚舉值
40         Season[] season = values();
41         
42         // 遍歷查找
43         for (Season s : season) {
44             if (s.name().equals(name)) {
45                 return true;
46             }
47         }
48         return false;
49     }
50 }
復制代碼

?


本文轉自SummerChill博客園博客,原文鏈接:http://www.cnblogs.com/DreamDrive/p/5632706.html,如需轉載請自行聯系原作者

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540223.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540223.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540223.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉載] 【Java】Java基礎知識及其擴展筆記(8千字)

參考鏈接&#xff1a; Java中的StringBuilder類及其示例 Java基礎知識及其擴展筆記 零 l 寫在前面一 l JVM1、【1.1.2.1】java程序運行的一般流程2、【1.1.2.1】JVM一般運行流程3、【1.1.2.1】JIT&#xff08;just in time 即時編譯編譯器&#xff09;4、堆與棧 二 l Java …

多IDC GSLB的部署

之前已經介紹過GSLB的實現原理&#xff0c;這里再向大家講述一下GSLB經常遇到的部署方式&#xff0c;多IDC的部署。很多大型的企業或業務容災要求非常高的客戶都會部署有多個異地的數據中心&#xff0c;以保證其業務的“全天候”不間斷的正常運行&#xff0c;而要整合多個IDC的…

[轉載] Controller報錯:java.lang.NoSuchMethodException: java.util.List.<init>()

參考鏈接&#xff1a; Java8中的java.util.StringJoiner 報錯詳情&#xff1a; java.lang.NoSuchMethodException: java.util.List.<init>() 以及 No primary or default constructor found for interface java.util.List 示例&#xff1a; /** * 此接口會產生以…

[轉載] 算法競賽中的JAVA使用筆記

參考鏈接&#xff1a; Java中StringTokenizer類的示例| 1(構造函數) 算法競賽中的JAVA使用筆記 算法競賽中的JAVA使用筆記 輸入與輸出 基本輸入輸入掛輸出控制臺輸入輸出重定向到文件 大整數與高精度 大整數BigInteger高精度BigDecimal高精度開方 字符串與進制轉換 字符串基本…

信息系統開發平臺OpenExpressApp:【OpenTest】 之 語法及其使用介紹

在OpenTest 之 運行環境準備中介紹了運行自動化測試需要做的一些準備工作&#xff0c;本篇將繼續給大家介紹OpenTest的腳本語法以及使用方法&#xff0c;通過學習后讀者應該能夠開始動手編寫UI自動化測試腳本了。 關鍵字驅動測試 在學習語法之前&#xff0c;需要了解一下關鍵字…

[轉載] java常量池-字符串常量池、class常量池和運行時常量池

參考鏈接&#xff1a; 如何在Java中初始化和比較字符串 原文鏈接&#xff1a;http://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/ 在java的內存分配中&#xff0c;經常聽到很多關于常量池的描述&#xff0c;我開始看的時候也是看的很模糊&#xff0c…

Oracle 10g 高級安裝圖文教程(二)

第八步&#xff1a;為了簡便起見&#xff08;工作中肯定不安全&#xff09;&#xff0c;選擇“所有的帳戶都是用同一個口令”&#xff0c;并輸入口令&#xff0c;點擊“下一步”&#xff1a;本文轉自 victoryan 51CTO博客&#xff0c;原文鏈接:http://blog.51cto.com/victoryan…

[轉載] StringBuffer和StringBuilder類

參考鏈接&#xff1a; Java中的String vs StringBuilder vs StringBuffer 下述文章資料來源于&#xff1a; W3CSCHOOL離線版的Java教程 Java JDK 6.0開發手冊 Java開發從入門到精通(陳小玉版) StringBuffer和String選擇的異同 StringBuffer在進行字符串處理時&#xff0c;不…

sharepoint 2007功能增強解決方案,資料收集

一、關于QuickFlow&#xff0c;sharepoint可視化工作流增強包 http://www.cnblogs.com/jianyi0115/tag/QuickFlow/default.html?page1 http://quickflow.codeplex.com/ 二、關于SharePoint Permission Extension&#xff0c;視圖、列表字段權限功能增強 http://sppex.codeplex…

[轉載] 面試題:說說Java中接口、類、成員變量、成員方法、構造方法有哪些訪問修飾符和他們的作用范圍

參考鏈接&#xff1a; Java中的訪問修飾符 * 問題&#xff1a;說說Java中接口、類、成員變量、成員方法、構造方法有哪些訪問修飾符和他們的作用范圍 * 答&#xff1a;接口的訪問修飾符只有public 1個 * 類的訪問修飾符有public和默認(就是不寫的)2個 * 成員方法的訪問修…

使用IHttpHandler做權限控制[ASP.NET | IHttpHandler | AjaxPro | UserHostName]

正文 Web.Config配置如下: <add verb"POST,GET"path"/page/*.aspx,/page/*/*.aspx,/page/*/*/*.aspx,/page/*/*/*/*.aspx,/page/*/*/*/*/*.aspx"type"WebLibrary.PowerManage.HttpHanderPowerControls"/> 整個IHttpHandler實現代碼如下: /…

[轉載] Java 中字符串轉整型和整型轉字符串

參考鏈接&#xff1a; Java中的字符串到整數– parseInt() Java 中字符串轉整型和整型轉字符串 1.字符串轉整型Java代碼&#xff0c;字符串為純數字的情況下&#xff0c;調用Integer的靜態方法parseInt或者valueOfJava代碼&#xff0c;如果單個字符或字符串&#xff0c;需要切…

Gram matrix 格拉姆矩陣

2019獨角獸企業重金招聘Python工程師標準>>> Gram matrix 度量各個維度自己的特性以及各個維度之間的關系。 來自&#xff1a;https://www.zhihu.com/question/49805962?fromprofile_question_card 由感知機&#xff08;對偶感知機中需要計算樣本點兩兩之間的內積和…

[轉載] 用Java語言實現對十六進制字符串異或運算

參考鏈接&#xff1a; 交換兩個字符串&#xff0c;而無需在Java中使用第三個用戶定義的變量 前言&#xff1a;好久沒有寫博客&#xff0c;最近一年感覺真是好忙&#xff0c;各種做不完的工作。相信很多上班族都會有這種感覺。最近對NFC進行寫卡操作&#xff0c;需要計算一個校…

MySQL日常應用操作記錄

1.知道一個字段名&#xff0c;怎樣查到它在數據庫里的哪張表里&#xff1f; USE Information_schema;SELECT TABLE_NAME FROM COLUMNS WHERE COLUMN_NAME字段名稱; MySQL中查看庫表字段信息都在information_schemal中&#xff0c;獲取數據字典等信息都要通過這個視圖。 如&…

[轉載] 【Java】將一個字符串的字符排序,按ASCII表的順序從小到大

參考鏈接&#xff1a; 在Java中搜索字符串中的字符和子字符串 將一個字符串的字符按ASCII表的順序從小到大排序&#xff0c;如將字符串“asdafxcvMADb”排序為“ADMaabcdfsvx” 算法的基本思想&#xff1a; 先將字符串轉化為一個char類型的數組&#xff0c;來進行存儲&#xf…

如果只做前端驗證的話,談jjdd.com的看照片功能。

如果你在上海&#xff0c;并且坐過地鐵的話&#xff0c;你肯定知道jjdd.com。 這個網站和百合&#xff0c;世紀佳緣類似&#xff0c;都是交朋友的性質。 在jjdd.com中有個很重要的功能&#xff1a;如果你上傳的照片比你想看的人少的話&#xff0c;你是不能看她的照片的。 例如如…

[轉載] 快速學習-Mybatis框架概述

參考鏈接&#xff1a; Java在競爭性編程中的快速I/O 第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架&#xff08;Framework&#xff09;是整個或部分系統的可重用設計&#xff0c;表現為一組抽象構件及構件實例間交互的方法;另一種定義認為&#xff0c;框架是可被…

3、MySQL的數據類型介紹

上一章節內容主要介紹了一些MySQL中對表和庫的增刪改查操作&#xff0c;對于上一章中對與表中字段的一些定義進行說明&#xff0c;本章主要介紹關于數據庫類型的一些定義。一、概述&#xff1a;MySQL數據庫中的數據大致可以分為以下幾類&#xff0c;從而實現數據庫在操作的時候…

[轉載] 必須要會回答的Java面試題(字符串篇)

參考鏈接&#xff1a; 比較Java中的兩個字符串String 最近很多學習java的小白問我字串相關的問題&#xff0c;覺得很有必要整理下&#xff0c;以方便初學者理解字符串以及應對今后面試中考官的提問。 如果你是有幾年Java開發經驗&#xff0c;可以根據目錄選擇性的閱讀以下內…