Java枚舉:覆寫toString,再看equals、hashCode – JAVA編程語言程序開發技術文章

仍然采用 Java 枚舉:理解枚舉本質 例子。稍加修改。

[java] 
package mark.demo; 
 
public class EnumDemo { 
 
    public static void main(String[] args) { 
        for (Color color : Color.values()) { 
            System.out.println(color); 
        } 
    } 
 
    public enum Color { 
        RED("red color", 0), GREEN("green color", 1), BLUE("blue color", 2), YELLOW( 
                "yellow color", 3); 
 
        Color(String name, int id) { 
            _name = name; 
            _id = id; 
        } 
 
        private String _name; 
        private int _id; 
 
        public String getName() { 
            return _name; 
        } 
 
        public int getId() { 
            return _id; 
        } 
    } 
 

打印結果

 


原本以為會打印如下形式的東西

 

 

但是,實際情況不是這樣。具體可以查看 Enum 的源碼,看看 toString 方法:

[java] 
/**
  * Returns the name of this enum constant, as contained in the
  * declaration.  This method may be overridden, though it typically
  * isn't necessary or desirable.  An enum type should override this
  * method when a more "programmer-friendly" string form exists.
  *
  * @return the name of this enum constant
  */ 
 public String toString() { 
turn name; 
 } 

註釋寫的很明白,返回的是 the name of enum constant(枚舉常量值的名字)。

如果我們想要得到如期的結果,需要重寫 toString 方法。

[java] 
package mark.demo; 
 
public class EnumDemo { 
 
    public static void main(String[] args) { 
        for (Color color : Color.values()) { 
            System.out.println(color); 
        } 
    } 
 
    public enum Color { 
        RED("red color", 0), GREEN("green color", 1), BLUE("blue color", 2), YELLOW( 
                "yellow color", 3); 
 
        Color(String name, int id) { 
            _name = name; 
            _id = id; 
        } 
 
        private String _name; 
        private int _id; 
 
        public String getName() { 
            return _name; 
        } 
 
        public int getId() { 
            return _id; 
        } 
         
        @Override 
        public String toString() { 
            return _name + "," + _id; 
        } 
    } 

上面代碼裡面使用增強 for 循環調用 values() 方法,遍歷枚舉的值,也可以這樣來遍歷:

[java] 
for (Color color : Color.values()) { 
    System.out.println(color.getName() + "," + color.getId()); 

 


Enum 類的 equals、hashCode 方法

[java] 
/**
    * Returns true if the specified object is equal to this
    * enum constant.
    *
    * @param other the object to be compared for equality with this object.
    * @return  true if the specified object is equal to this
    *          enum constant.
    */ 
   public final boolean equals(Object other) {  
       return this==other; 
   } 
 
   /**
    * Returns a hash code for this enum constant.
    *
    * @return a hash code for this enum constant.
    */ 
   public final int hashCode() { 
       return super.hashCode(); 
   } 

都是 final 的,很明顯,設計者不想讓子類去重寫這兩個方法。

的確,在枚舉裡面無法重寫這兩個方法。但是如何使用這個方法呢?

現在,我們不去重寫 toString 方法,看看 equals 效果。

[java] 
public enum Color { 
        RED("red color", 0), GREEN("green color", 1),  
        BLUE("blue color", 2), YELLOW("yellow color", 3); 
 
        Color(String name, int id) { 
            _name = name; 
            _id = id; 
        } 
 
        private String _name; 
        private int _id; 
 
        public String getName() { 
            return _name; 
        } 
 
        public int getId() { 
            return _id; 
        } 

測試結果:

[java] 
public static void main(String[] args) { 
        System.out.println(Color.RED.equals(""));// false 
        System.out.println(Color.RED.equals("red color"));// false 
        System.out.println(Color.RED.equals("RED"));// false 
        System.out.println(Color.RED.equals(Color.BLUE));// false 
        // 同一個對象 
        System.out.println(Color.RED.equals(Color.RED));// true 
        // 實際是兩個 String 
        System.out.println(Color.RED.toString().equals("RED"));// true 
        // 實際是兩個 String 
        System.out.println(Color.RED.getName().equals("red color"));// true 
        // hashCode 
        System.out.println("Color.RED.hashCode = " + Color.RED.hashCode()); 

如果重寫瞭類似上面的 toString 方法,那麼

[java] view plaincopyprint?
System.out.println(Color.RED.toString().equals("RED")); 

返回的可能是 true,也可能是 false,這取決於你的 toString 具體實現。
 
如下面這種實現方法:返回 _name 的大寫形式。

[java]
@Override 
        public String toString() { 
            return this._name.toUpperCase(); 
        } 

綜上,建議根據需要可以重寫 toString 方法,善用 equals 方法。

 

 

 

 

 

 

發佈留言