成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Coder,我懷疑你并不會枚舉

開發 后端
關于枚舉,阿里巴巴開發手冊有這樣兩條建議:枚舉類名帶上 Enum 后綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。

[[337601]]

枚舉是JDK1.5引入的新特性。被enum關鍵字修飾的類就是一個枚舉類。

關于枚舉,阿里巴巴開發手冊有這樣兩條建議:

枚舉類名帶上 Enum 后綴,枚舉成員名稱需要全大寫,單詞間用下劃線隔開。

如果變量值僅在一個固定范圍內變化用 enum 類型來定義。

一 枚舉類有哪些特點

創建一個ColorEnum的枚舉類,通過編譯,再反編譯看看它發生了哪些變化。

  1. public enum ColorEnum { 
  2.     RED,GREEN,BULE; 

使用命令javac ColorEnum.java進行編譯生成class文件,然后再用命令javap -p ColorEnum.class進行反編譯。

 

去掉包名,反編譯后的內容如下:

  1. public final class ColorEnum extends Enum{ 
  2.     public static final ColorEnum GREEN; 
  3.     public static final ColorEnum BULE; 
  4.     private static final ColorEnum[] $VALUES
  5.     public static ColorEnum[] values(); 
  6.     public static ColorEnum valueOf(java.lang.String); 
  7.     private ColorEnum(); 
  8.     static {}; 
  1. 枚舉類被final修飾,因此枚舉類不能被繼承;
  2. 枚舉類默認繼承了Enum類,java不支持多繼承,因此枚舉類不能繼承其他類;
  3. 枚舉類的構造器是private修飾的,因此其他類不能通過構造器來獲取對象;
  4. 枚舉類的成員變量是static修飾的,可以用類名.變量來獲取對象;
  5. values()方法是獲取所有的枚舉實例;
  6. valueOf(java.lang.String)是根據名稱獲取對應的實例;

二 枚舉創建線程安全的單例模式

  1. public enum  SingletonEnum { 
  2.  
  3.     INSTANCE; 
  4.  
  5.     public void doSomething(){ 
  6.         // dosomething... 
  7.     } 

這樣一個單例模式就創建好了,通過SingletonEnum.INSTANCE來獲取對象就可以了。

2.1 序列化造成單例模式不安全

一個類如果如果實現了序列化接口,則可能破壞單例。每次反序列化一個序列化的一個實例對象都會創建一個新的實例。

枚舉序列化是由JVM保證的,每一個枚舉類型和定義的枚舉變量在JVM中都是唯一的,在枚舉類型的序列化和反序列化上,Java做了特殊的規定:在序列化時Java僅僅是將枚舉對象的name屬性輸出到結果中,反序列化的時候則是通過java.lang.Enum的valueOf方法來根據名字查找枚舉對象。同時,編譯器是不允許任何對這種序列化機制的定制的并禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法,從而保證了枚舉實例的唯一性。

2.2 反射造成單例模式不安全

通過反射強行調用私有構造器來生成實例對象,造成單例模式不安全。

  1. Class<?> aClass = Class.forName("xx.xx.xx"); 
  2. Constructor<?> constructor = aClass.getDeclaredConstructor(String.class); 
  3. SingletonEnum singleton = (SingletonEnum) constructor.newInstance("Java旅途"); 

但是使用枚舉創建的單例完全不用考慮這個問題,來看看newInstance的源碼!

  1. public T newInstance(Object ... initargs) 
  2.     throws InstantiationException, IllegalAccessException, 
  3. IllegalArgumentException, InvocationTargetException 
  4.     if (!override) { 
  5.         if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { 
  6.             Class<?> caller = Reflection.getCallerClass(); 
  7.             checkAccess(caller, clazz, null, modifiers); 
  8.         } 
  9.     } 
  10.     // 如果是枚舉類型,直接拋出異常,不讓創建實例對象! 
  11.     if ((clazz.getModifiers() & Modifier.ENUM) != 0) 
  12.         throw new IllegalArgumentException("Cannot reflectively create enum objects"); 
  13.     ConstructorAccessor ca = constructorAccessor;   // read volatile 
  14.     if (ca == null) { 
  15.         ca = acquireConstructorAccessor(); 
  16.     } 
  17.     @SuppressWarnings("unchecked"
  18.     T inst = (T) ca.newInstance(initargs); 
  19.     return inst; 

如果是enum類型,則直接拋出異常Cannot reflectively create enum objects,無法通過反射創建實例對象!

三 通過枚舉消除if/else

假如要寫一套加密接口,分別給小程序、app和web端來使用,但是這三種客戶端的加密方式不一樣。一般情況下我們會傳一個類型type來判斷來源,然后調用對應的解密方法即可。代碼如下:

  1. if("WEIXIN".equals(type)){ 
  2.     // dosomething 
  3. }else if("APP".equals(type)){ 
  4.     // dosomething 
  5. }else if("WEB".equals(type)){ 
  6.     // dosomething 

現在使用枚舉來消除這些if/else。

寫一個加密用的接口,有加密和解密兩個方法。然后用不同的算法去實現這個接口完成加解密。

  1. public interface Util { 
  2.  
  3.     // 解密 
  4.     String decrypt(); 
  5.  
  6.     // 加密 
  7.     String encrypt(); 

創建一個枚舉類來實現這個接口

  1. public enum UtilEnum implements Util { 
  2.  
  3.     WEIXIN { 
  4.         @Override 
  5.         public String decrypt() { 
  6.             return "微信解密"
  7.         } 
  8.  
  9.         @Override 
  10.         public String encrypt() { 
  11.             return "微信加密"
  12.         } 
  13.     }, 
  14.     APP { 
  15.         @Override 
  16.         public String decrypt() { 
  17.             return "app解密"
  18.         } 
  19.  
  20.         @Override 
  21.         public String encrypt() { 
  22.             return "app加密"
  23.         } 
  24.     }, 
  25.     WEB { 
  26.         @Override 
  27.         public String decrypt() { 
  28.             return "web解密"
  29.         } 
  30.  
  31.         @Override 
  32.         public String encrypt() { 
  33.             return "web加密"
  34.         } 
  35.     }; 

最后,獲取到type后,直接調用解密方法就行了。

  1. String decryptMessage = UtilEnum.valueOf(type).decrypt(); 

以后,如果新增了一個其他加密方式,只需要修改上面的枚舉類就完成了,業務代碼都不需要改動。

 

這就是枚舉類比較高級的兩個用法。

本文轉載自微信公眾號「Java旅途」,可以通過以下二維碼關注。轉載本文請聯系Java旅途公眾號。

 

責任編輯:武曉燕 來源: Java旅途
相關推薦

2018-03-09 12:40:41

內存降價國產

2019-03-29 15:13:59

數據中心Spiceworks服務器

2016-05-24 11:33:50

網絡基礎設施公有云軟件即服務

2013-05-10 09:17:23

2015-08-13 10:28:29

網絡詐騙手機實名制

2019-01-16 10:40:08

2016-03-03 15:00:50

智能記錄數據

2020-06-24 09:00:43

分庫分表MySQL

2020-05-14 08:59:28

API網關性能

2021-09-14 09:19:49

一號多卡手機卡號碼

2021-12-31 18:24:45

ThreadLocal數據庫對象

2020-11-01 17:00:04

重載重寫java

2017-10-31 10:12:12

無人駕駛安全性乘客信任

2016-04-28 09:36:44

人才教育/華三

2022-08-01 08:17:46

mysqlwindows系統

2015-03-16 11:33:16

程序員代碼bug

2022-08-08 20:33:12

VolatileJVM

2019-07-01 14:44:23

Java互聯網代碼

2020-02-22 21:45:00

TypeScriptJavaScript瀏覽器

2025-04-08 11:30:00

DIM數據倉庫架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品国产乱码久久久久久88av | 精品91视频| 免费h在线 | www国产成人免费观看视频,深夜成人网 | 日韩欧美在线一区二区 | 亚洲不卡在线观看 | 亚洲视频一区在线观看 | 国产福利在线播放 | 日韩成人免费视频 | 在线天堂免费中文字幕视频 | 久久国产成人精品国产成人亚洲 | 色香蕉在线 | 精品乱码一区二区三四区视频 | 欧美一区二区三区在线观看视频 | 中文字幕精品一区 | 精品无码久久久久久国产 | 免费一级欧美在线观看视频 | 欧美精品一区二区三区在线 | 国产欧美视频一区二区 | 国产高清精品一区二区三区 | 一级毛片免费 | 成人免费一区二区三区视频网站 | 全免费a级毛片免费看视频免 | 亚洲人成在线观看 | 国产一区二区三区 | 国产激情偷乱视频一区二区三区 | 1000部精品久久久久久久久 | 中文字幕色站 | 福利视频网| 国产精品中文 | 91高清视频在线观看 | 欧美久久一区二区 | 国产高清视频一区 | 欧美日韩一 | 欧美大片一区二区 | 亚洲视频在线免费观看 | 日本aⅴ中文字幕 | 久久精品国产一区二区三区不卡 | 国产一区| 视频一区中文字幕 | 在线免费中文字幕 |