Java 枚举:覆写 toString,再看 equals、hashCode

仍然采用 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 方法:

   /**
     * 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() {
	return name;
    }

注释写的很明白,返回的是 the name of enum constant(枚举常量值的名字)。


如果我们想要得到如期的结果,需要重写 toString 方法。

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() 方法,遍历枚举的值,也可以这样来遍历:

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



Enum 类的 equals、hashCode 方法

 /**
     * 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 效果。

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;
		}
}


测试结果:

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 方法,那么

System.out.println(Color.RED.toString().equals("RED"));


返回的可能是 true,也可能是 false,这取决于你的 toString 具体实现。
 

如下面这种实现方法:返回 _name 的大写形式。

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


综上,建议根据需要可以重写 toString 方法,善用 equals 方法。








©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页