日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

语法糖甜不甜?巧用枚举实现“状态”转换限制

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 语法糖甜不甜?巧用枚举实现“状态”转换限制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

語法糖

語法糖(Syntactic sugar),也被譯為糖衣語法,是由英國計算機科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語,指計算機語言中添加的某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機會。——摘抄自百度百科

本質上,JVM 并不支持語法糖,語法糖只存在于編譯期。當編譯器將 .java 源文件編譯成 .class 字節碼文件時,會進行解語法糖的操作,來還原最原始的基礎語法結構。

我們所熟悉的編程語言中幾乎都會包含語法糖,當然 JAVA 也不例外。JAVA 中的語法糖包含條件編譯斷言switch 支持 String 與枚舉可變參數自動裝箱/拆箱枚舉內部類泛型擦除增強for循環lambda表達式try-with-resources等等。今天我們先來了解下枚舉

?

枚舉類

JDK5 提供了一種新的特殊的類——枚舉類,一般在類對象有限且固定的場景下使用,用來替代類中定義常量的方式。枚舉相較于常量更加直觀且類型安全。

枚舉類的使用非常簡單,用 enum 關鍵字來定義,多個枚舉變量直接用逗號隔開。我們先來定義一個簡單的枚舉類 OrderStatus.java

public?enum?OrderStatus?{//未支付、已支付、退款中、退款成功、退款失敗;NO_PAY,?PAY,?REFUNDING,?REFUNDED,?FAIL_REFUNDED,?; }

在其他類中使用 enum 變量的時候,只需要【類名.變量名】就可以了,和使用靜態變量一樣。另外,枚舉類型可以確保 JVM 中僅存在一個常量實例,所以我們可以放心的使用“ ==”來比較兩個變量。

注意事項:

  • 枚舉類的第一行必須是枚舉項,最后一個枚舉項后的分號是可以省略的,但是如果枚舉類有其它的東西,這個分號就不能省略。建議不要省略!

  • 枚舉變量最好大寫,多個單詞之間使用”_”隔開(比如:NO_PAY)。

  • 反編譯

    我們可以先通過 javac 命令或者 IDEA 的編譯功能將OrderStatus.java 編譯為OrderStatus.class 字節碼文件,然后用DJ Java Decompiler 反編譯器對 .class 文件進行反編譯。

    如果需要 DJ Java Decompiler 反編譯器的小伙伴可以私信阿Q獲取!

    public?final?class?OrderStatus?extends?Enum {//該方法會返回包括所有枚舉變量的數組,可以方便的用來做循環。public?static?OrderStatus[]?values(){return?(OrderStatus[])$VALUES.clone();}//根據傳入的字符串,轉變為對應的枚舉變量。//前提是傳的字符串和定義枚舉變量的字符串一抹一樣,區分大小寫。//如果傳了一個不存在的字符串,那么會拋出異常。public?static?OrderStatus?valueOf(String?name){return?(OrderStatus)Enum.valueOf(com/itcast/java/enumpack/OrderStatus,?name);}private?OrderStatus(String?s,?int?i){super(s,?i);}public?static?final?OrderStatus?NO_PAY;public?static?final?OrderStatus?PAY;public?static?final?OrderStatus?REFUNDING;public?static?final?OrderStatus?REFUNDED;public?static?final?OrderStatus?FAIL_REFUNDED;private?static?final?OrderStatus?$VALUES[];static?{NO_PAY?=?new?OrderStatus("NO_PAY",?0);PAY?=?new?OrderStatus("PAY",?1);REFUNDING?=?new?OrderStatus("REFUNDING",?2);REFUNDED?=?new?OrderStatus("REFUNDED",?3);FAIL_REFUNDED?=?new?OrderStatus("FAIL_REFUNDED",?4);$VALUES?=?(new?OrderStatus[]?{NO_PAY,?PAY,?REFUNDING,?REFUNDED,?FAIL_REFUNDED});} }

    如源碼所示:

    • 編譯器會自動幫我們創建一個 final 類型的類繼承 Enum 類,所以枚舉類不能被繼承。

    • 會自動生成私有構造方法,當然我們也可以定義構造方法,但必須是私有的,這樣就不能在別處聲明此類的對象了。

    • 枚舉項會被自動添加 public static final 修飾,并定義為 OrderStatus 類型,并在靜態代碼塊中被初始化。

    • 并提供了 values()valueOf(String name) 的靜態方法。

    我們定義的枚舉變量實際上是編譯器幫我們自動生成了構造函數。

    所有枚舉類都是 Enum 的子類,枚舉類可以實現一個或多個接口。

    Enum

    Enum 是所有 Java 語言枚舉類型的公共基類,實現了 Comparable 和 Serializable 接口。它包含 final 類型的 name 和 ordinal (此枚舉常量的序號,從0開始)屬性,下面我們來了解下它的方法

    • protected Enum(String name, int ordinal);——構造方法;

    • public String toString();——返回 name 字段,即枚舉定義枚舉變量的字符串;

    • protected final Object clone();——拋出 CloneNotSupportedException 異常,保證枚舉類永遠不會被克隆;

    • public final ClassgetDeclaringClass();——返回與此枚舉常量的枚舉類型對應的類對象;

    • protected final void finalize();—— 枚舉類不能有 finalize 方法;

    • readObject(ObjectInputStream in);& readObjectNoData();—— 拋出InvalidObjectException 異常,防止默認反序列化;

    擴展

  • 枚舉類中可以自定義屬性

    自定義的屬性值最好用 private final 修飾,防止生成的 set 方法在使用時修改屬性值,使代碼更加安全。

  • 枚舉類中可以自定義構造函數

    構造函數必須為 private 修飾,防止在別處聲明此類對象。

  • 枚舉類可以自定義方法,枚舉項可以選擇性覆蓋自定義的方法。

    public?enum?OrderStatus{NO_PAY("未支付",0),PAY("已支付",1){@Overridepublic?void?printOrderStatus()?{System.out.println("已支付");}},REFUNDING("退款中",2),REFUNDED("退款成功",3),FAIL_REFUNDED("退款失敗",4),;private?final?String?name;private?final?int?status;private?OrderStatus(String?name,int?status){this.name?=?name;this.status?=?status;}public?void?printOrderStatus(){System.out.println("打印訂單狀態");} }public?class?EnumTest?{public?static?void?main(String[]?args)?{OrderStatus.PAY.printOrderStatus();OrderStatus.NO_PAY.printOrderStatus();} }
  • 枚舉類也可以有抽象方法,但是枚舉項必須重寫該方法。

  • 枚舉類實現接口

    與普通類一樣,實現接口的時候需要實現接口的抽象方法,也可以讓枚舉類的不同對象實現不同的行為。

  • //定義一個接口 public?interface?Order?{void?printOrderStatus(); }//枚舉類實現該接口 public?enum?OrderStatus?implements?Order{NO_PAY("未支付",0){@Overridepublic?void?printOrderStatus()?{System.out.println("未支付");}},PAY("已支付",1){@Overridepublic?void?printOrderStatus()?{System.out.println("已支付");}},REFUNDING("退款中",2){@Overridepublic?void?printOrderStatus()?{System.out.println("退款中");}},REFUNDED("退款成功",3){@Overridepublic?void?printOrderStatus()?{System.out.println("退款成功");}},FAIL_REFUNDED("退款失敗",4){@Overridepublic?void?printOrderStatus()?{System.out.println("退款失敗");}},;private?final?String?name;private?final?int?status;private?OrderStatus(String?name,int?status){this.name?=?name;this.status?=?status;} }

    此時查看編譯后的文件,會發現除了生成 OrderStatus.class 文件之外,還生成了多個 .class 文件:

    它們是 OrderStatus.class 中生成的匿名內部類的文件。

    ?

    狀態轉換

    需求

    訂單是電商項目中不可缺少的組成部分,而訂單狀態的轉換也是我們經常討論的問題。我們都知道訂單狀態的轉換是有一定的邏輯性的,不可以隨意轉換。

    :你想購買某個商品,只是把它加入了購物車,此時應該是未支付狀態。如果來個請求想把它轉換為退款狀態,那么系統應該拋出提示信息“狀態轉換失敗,請先完成購買!”

    接下來我們就用枚舉來完成一下訂單狀態轉換的限制。

    實現

    枚舉類定義:

    public?enum?OrderStatus{NO_PAY("未支付",0){@Overridepublic?Boolean?canChange(OrderStatus?orderStatus)?{switch?(orderStatus){case?PAY:return?true;default:return?false;}}},PAY("已支付",1){@Overridepublic?Boolean?canChange(OrderStatus?orderStatus)?{//因為退款接口一般都會有延遲,所以會先轉化為“退款中”狀態switch?(orderStatus){case?REFUNDING:return?true;default:return?false;}}},REFUNDING("退款中",2){@Overridepublic?Boolean?canChange(OrderStatus?orderStatus)?{switch?(orderStatus){case?REFUNDED:case?FAIL_REFUNDED:return?true;default:return?false;}}},REFUNDED("退款成功",3),FAIL_REFUNDED("退款失敗",4),;private?final?String?name;private?final?int?status;private?OrderStatus(String?name,int?status){this.name?=?name;this.status?=?status;}//自定義轉換方法public?Boolean?canChange(OrderStatus?orderStatus){return?false;} }

    調用方法:

    public?class?EnumTest?{public?static?void?main(String[]?args)?{Boolean?aBoolean?=?OrderStatus.NO_PAY.canChange(OrderStatus.PAY);String?statusStr?=?aBoolean?"可以":"不可以";System.out.println("是否可以完成狀態轉換:"+?statusStr);Boolean?flag?=?OrderStatus.REFUNDED.canChange(OrderStatus.FAIL_REFUNDED);String?flagStr?=?flag?"可以":"不可以";System.out.println("是否可以完成狀態轉換:"+?flagStr);} }

    返回結果:

    這樣我們就用枚舉類實現了訂單狀態轉換的限制。此例子只是為狀態轉換提供一種思路,具體的流程還需要根據自己系統中的業務來具體處理。

    有道無術,術可成;有術無道,止于術

    歡迎大家關注Java之道公眾號

    好文章,我在看??

    總結

    以上是生活随笔為你收集整理的语法糖甜不甜?巧用枚举实现“状态”转换限制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 美女av免费观看 | 无码人妻丰满熟妇精品 | 自拍偷在线精品自拍偷无码专区 | 波多野吉衣视频在线观看 | 丰满少妇高潮一区二区 | 一个人看的www片免费高清中文 | 国产福利午夜 | 91精品网站| 国产不卡a | 国产毛片视频 | 欧美成人一区二区三区片免费 | 婷婷色在线| 天堂综合网久久 | 亚洲一区二区电影 | 久久短视频 | 操操操操操操 | 国产精品999 | av国产网站 | 亚洲午夜精品一区 | 97超碰资源站 | 国内外成人激情视频 | 亚洲精品无人区 | 亚洲午夜av | 69久久精品 | 亚洲国产日韩在线观看 | 国产美女久久 | 2021天天操 | 婷婷国产精品 | 91久久久久久久久久久久久 | 性猛交娇小69hd | 爱情岛亚洲品质自拍极速福利网站 | 国产精品自在线 | 老女人黄色片 | 日本少妇xxxx软件 | 久久婷五月 | 午夜av导航 | 波多野结衣在线影院 | 性色视频在线 | 得得的爱在线视频 | 无码人妻久久一区二区三区 | 中文字幕二 | 日韩人妻无码精品久久免费 | 亚洲一区二区三区四区五区午夜 | 久久久免费在线观看 | 国产精品亚洲一区二区三区在线观看 | 日韩激情网址 | 蜜臀av无码精品人妻色欲 | 青青草99 | 少妇被又大又粗又爽毛片久久黑人 | 中文字幕在线一区二区三区 | 夜色一区二区三区 | 黄色一级大片在线观看 | 国产大片一区二区 | 超碰av免费| 国产精品白浆一区二小说 | 亚洲无毛 | 青青国产 | 91亚洲精品一区二区乱码 | 美女黄色一级视频 | 99热这里有精品 | 久久国产网站 | 亚洲男女 | 手机看片一区二区 | 亚久久 | 天天躁日日躁狠狠躁 | av永久 | 中文字幕在线观看日韩 | 毛片.com| 第四色激情| 夜夜福利 | 亚洲一区二区三区在线播放 | 黄色激情网站 | 日韩成人av电影 | 一本色道久久88加勒比—综合 | 狠狠爱网站 | 免费网站在线高清观看 | 欧美特级aaa | 性网站在线观看 | 色悠悠网 | 一区二区三区在线视频观看 | 超碰av免费 | 免费在线网站 | 国家队动漫免费观看在线观看晨光 | 91视频一区二区三区 | 波多野结衣在线电影 | 97色在线 | 日韩激情一区二区三区 | 国内毛片视频 | 中文字幕av影院 | 黄黄的视频在线观看 | 中文字幕久久久久久久 | 亚洲一区二区精品视频 | 亚洲精品免费在线观看 | 日韩精品电影在线观看 | 欧美99久久精品乱码影视 | 最近中文字幕在线观看视频 | 欧美韩国一区 | 亚洲精品天堂成人片av在线播放 | 人妻人人澡人人添人人爽 |