欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 枚舉類定義靜態(tài)valueOf(java.lang.String)方法的問題及解決

 更新時間:2021年09月13日 10:41:48   作者:NetWhite  
這篇文章主要介紹了java 枚舉類定義靜態(tài)valueOf(java.lang.String)方法的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

問題的起因

起因來自于我對于java枚舉類的無知。

我本來想定義這樣一個枚舉類:

public enum MenuOptions { 
    CHAT_ROOM("#1"),
    MENU("#0"),
    ERROR("#9999");
 
    private String value;
 
    MenuOptions(String value) {
        this.value = value;
    }
 
    @Override
    public String toString() {
        return value;
    }
 
    // 根據(jù)字符串的值返回枚舉常量
    public static MenuOptions valueOf(String value) {
        //...
        return MenuOptions.ERROR;
    } 
}

關(guān)鍵是定義的這個方法:

我用的IDE是IDEA,jdk版本是1.8,但是編譯版本、語言級別是1.7

這里報方法定義已存在,,,???

這個時候,想起來枚舉類有一個valueOf方法的,傳入的參數(shù)是枚舉常量的變量名,返回這個枚舉常量,然后debug,發(fā)現(xiàn)枚舉類內(nèi)部調(diào)用了java.lang.Enum類的這個方法:

    public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    }

猜測、分析

猜測可能是編譯的時候,這個類被JDK默認(rèn)繼承了Enum類,通過IDEA查看class反編譯文件:

what???什么也沒有。。。

使用javap來看這個class文件:

首先,確實可以看到這個類繼承自Enum類,然后這個類valueOf(String)調(diào)用了Enum.valueOf(Class,String)方法:

but,這個類的valueOf(String)在Enum類里沒有找到(下面是Enum類的所有方法聲明):

這樣看來是JDK編譯的時候,動態(tài)增加的,不知道猜想是否準(zhǔn)確,回頭找個時間好好查下資料了解下。

最終解決方案

碰見這樣的,我也不知道怎么解決了,本來我這個方法,是想通過傳入的值返回相應(yīng)的枚舉值,不是像默認(rèn)的那樣傳入枚舉量的變量名字符串。

那這樣的話,我只能換個名了,,,尷尬。。。如下完整代碼 :

public enum MenuOptions { 
    CHAT_ROOM("#1"),
    MENU("#0"),
    ERROR("#9999"){
        {
            innerMap.put("#1", "CHAT_ROOM");
            innerMap.put("#0", "MENU");
            innerMap.put("#9999", "ERROR");
        }
    };
 
    private String value;
    protected Map<String, String> innerMap = new HashMap<>();
 
    MenuOptions(String value) {
        this.value = value;
    }
 
    @Override
    public String toString() {
        return value;
    }
 
    // 根據(jù)字符串的值返回枚舉常量
    public static MenuOptions valueOf2(String value) {
        String name = MenuOptions.ERROR.innerMap.get(value.trim().intern());
        if (name == null) {
            return MenuOptions.ERROR;
        }
        MenuOptions option = valueOf(name);
 
        return option;
    } 
}

枚舉類Enum方法簡介(valueof,value,ordinal)

Enum作為Sun全新引進(jìn)的一個關(guān)鍵字,看起來很象是特殊的class, 它也可以有自己的變量,可以定義自己的方法,可以實現(xiàn)一個或者多個接口。 當(dāng)我們在聲明一個enum類型時,

我們應(yīng)該注意到enum類型有如下的一些特征

1.它不能有public的構(gòu)造函數(shù),這樣做可以保證客戶代碼沒有辦法新建一個enum的實例。

2.所有枚舉值都是public , static , final的。注意這一點(diǎn)只是針對于枚舉值,我們可以和在普通類里面定義 變量一樣定義其它任何類型的非枚舉變量,這些變量可以用任何你想用的修飾符。

3.Enum默認(rèn)實現(xiàn)了java.lang.Comparable接口。

4.Enum覆載了了toString方法,因此我們?nèi)绻{(diào)用Color.Blue.toString()默認(rèn)返回字符串”Blue”.

5.Enum提供了一個valueOf方法,這個方法和toString方法是相對應(yīng)的。調(diào)用valueOf(“Blue”)將返回Color.Blue.因此我們在自己重寫toString方法的時候就要注意到這一點(diǎn),一把來說應(yīng)該相對應(yīng)地重寫valueOf方法。

6.Enum還提供了values方法,這個方法使你能夠方便的遍歷所有的枚舉值。

7.Enum還有一個oridinal的方法,這個方法返回枚舉值在枚舉類種的順序,這個順序根據(jù)枚舉值聲明的順序而定,這里Color.Red.ordinal()返回0。

了解了這些基本特性,我們來看看如何使用它們

1.遍歷所有有枚舉值. 知道了有values方法,我們可以輕車熟路地用ForEach循環(huán)來遍歷了枚舉值了。

  for   (Color   c:   Color.values())   
  System.out.println(“find   value:”   +   c);   

2.在enum中定義方法和變量,比如我們可以為Color增加一個方法隨機(jī)返回一個顏色。

public   enum   Color   {   
  Red,   
  Green,   
  Blue;   
  /*   
  *定義一個變量表示枚舉值的數(shù)目。   
  *(我有點(diǎn)奇怪為什么sun沒有給enum直接提供一個size方法).   
  */   
  private   static   int   number   =   Color.values().length   ;   
  /**   
  *   隨機(jī)返回一個枚舉值   
  @return   a   random   enum   value.   
  */   
  public   static   Color   getRandomColor(){   
  long   random   =   System.currentTimeMillis()   %   number;   
  switch   ((int)   random){   
   case   0:   
    return   Color.Red;   
   case   1:   
    return   Color.Green;   
   case   2:   
    return   Color.Blue;   
   default   :   return   Color.Red;   
  }   
  }   
  }   

可以看出這在枚舉類型里定義變量和方法和在普通類里面定義方法和變量沒有什么區(qū)別。唯一要注意的只是變量和方法定義必須放在所有枚舉值定義的后面,否則編譯器會給出一個錯誤。

3.覆載(Override)toString, valueOf方法

前面我們已經(jīng)知道enum提供了toString,valueOf等方法,很多時候我們都需要覆載默認(rèn)的toString方法,那么對于enum我們怎么做呢。其實這和覆載一個普通class的toString方法沒有什么區(qū)別。

….   
  public   String   toString(){   
  switch   (this){   
  case   Red:   
   return   "Color.Red ";   
  case   Green:   
   return   "Color.Green ";   
  case   Blue:   
   return   "Color.Blue ";   
  default:   
   return   "Unknow   Color ";   
  }   
  }   
  ….   

這時我們可以看到,此時再用前面的遍歷代碼打印出來的是

  Color.Red
  Color.Green
  Color.Blue

而不是

  Red
  Green
  Blue.

可以看到toString確實是被覆載了。一般來說在覆載toString的時候我們同時也應(yīng)該覆載valueOf方法,以保持它們相互的一致性。

4.使用構(gòu)造函數(shù)

雖然enum不可以有public的構(gòu)造函數(shù),但是我們還是可以定義private的構(gòu)造函數(shù),在enum內(nèi)部使用。還是用Color這個例子。

public   enum   Color   {   
  Red( "This   is   Red "),   
  Green( "This   is   Green "),   
  Blue( "This   is   Blue ");   
  private   String   desc;   
  Color(String   desc){   
  this.desc   =   desc;   
  }   
  public   String   getDesc(){   
  return   this.desc;   
  }   
  }   

這里我們?yōu)槊恳粋€顏色提供了一個說明信息, 然后定義了一個構(gòu)造函數(shù)接受這個說明信息。

要注意這里構(gòu)造函數(shù)不能為public或者protected, 從而保證構(gòu)造函數(shù)只能在內(nèi)部使用,客戶代碼不能new一個枚舉值的實例出來。這也是完全符合情理的,因為我們知道枚舉值是public static final的常量而已。

5.實現(xiàn)特定的接口

我們已經(jīng)知道enum可以定義變量和方法,它要實現(xiàn)一個接口也和普通class實現(xiàn)一個接口一樣,這里就不作示例了。

6.定義枚舉值自己的方法。

前面我們看到可以為enum定義一些方法,其實我們甚至可以為每一個枚舉值定義方法。這樣,我們前面覆載 toString的例子可以被改寫成這樣。

  public   enum   Color   {   
  Red   {   
  public   String   toString(){   
   return   "Color.Red ";   
  }   
  },   
  Green   {   
  public   String   toString(){   
   return   "Color.Green ";   
  }   
  },   
  Blue{   
  public   String   toString(){   
   return   "Color.Blue ";   
  }   
  };   
  }  

從邏輯上來說這樣比原先提供一個“全局“的toString方法要清晰一些。

總的來說,enum作為一個全新定義的類型,是希望能夠幫助程序員寫出的代碼更加簡單易懂,個人覺得一般也不需要過多的使用enum的一些高級特性,否則就和簡單易懂的初衷想違背了。希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot中創(chuàng)建bean的7種方式總結(jié)

    SpringBoot中創(chuàng)建bean的7種方式總結(jié)

    Spring是一款廣泛應(yīng)用于企業(yè)級應(yīng)用程序開發(fā)的Java框架,其 IOC 和 DI 特性可以有效地管理應(yīng)用程序中的對象,提高了應(yīng)用程序的可維護(hù)性和可擴(kuò)展性,那你知道spring有哪些方式將bean放入容器嘛,今天就給大家總結(jié)一下
    2023-07-07
  • Java BigDecimal案例詳解

    Java BigDecimal案例詳解

    這篇文章主要介紹了Java BigDecimal案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • SpringBoot監(jiān)控SQL運(yùn)行情況的流程步驟

    SpringBoot監(jiān)控SQL運(yùn)行情況的流程步驟

    Druid是Java語言中最好的數(shù)據(jù)庫連接池,雖然?HikariCP?的速度稍快,但是,Druid能夠提供強(qiáng)大的監(jiān)控和擴(kuò)展功能?,也是阿里巴巴的開源項目,本文給大家介紹了SpringBoot監(jiān)控SQL運(yùn)行情況的流程步驟,需要的朋友可以參考下
    2024-03-03
  • 利用idea快速搭建一個spring-cloud(圖文)

    利用idea快速搭建一個spring-cloud(圖文)

    本文主要介紹了idea快速搭建一個spring-cloud,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • List轉(zhuǎn)變?yōu)槎禾柗指舻腟tring(Java7和Java8分別實現(xiàn))

    List轉(zhuǎn)變?yōu)槎禾柗指舻腟tring(Java7和Java8分別實現(xiàn))

    這篇文章主要介紹了Java7和Java8分別實現(xiàn)List轉(zhuǎn)變?yōu)槎禾柗指舻腟tring,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • IDEA手動添加junit4時出現(xiàn)的問題與解決方法

    IDEA手動添加junit4時出現(xiàn)的問題與解決方法

    這篇文章主要給大家介紹了關(guān)于IDEA手動添加junit4時出現(xiàn)的問題與解決方法,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 手把手帶你粗略了解Java--類和對象

    手把手帶你粗略了解Java--類和對象

    這篇文章主要給大家介紹了關(guān)于java中類和對象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Eclipse中配置Maven的圖文教程

    Eclipse中配置Maven的圖文教程

    這篇文章主要介紹了Eclipse中配置Maven的圖文教程,需要的朋友可以參考下
    2020-12-12
  • Spring依賴注入與第三方Bean管理基礎(chǔ)詳解

    Spring依賴注入與第三方Bean管理基礎(chǔ)詳解

    依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個概念。具體含義是:當(dāng)某個角色(可能是一個Java實例,調(diào)用者)需要另一個角色(另一個Java實例,被調(diào)用者)的協(xié)助時,在 傳統(tǒng)的程序設(shè)計過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實例
    2022-12-12
  • 基于java內(nèi)部類作用的深入分析

    基于java內(nèi)部類作用的深入分析

    本篇文章介紹了,基于java內(nèi)部類作用的深入分析。需要的朋友參考下
    2013-05-05

最新評論