- PR -

EnumのvalueOf()

1
投稿者投稿内容
やじゅう
常連さん
会議室デビュー日: 2005/08/10
投稿数: 34
お住まい・勤務地: 野獣の住処
投稿日時: 2007-02-19 20:06
Enumを拡張し、実際のデータ値は"O2"や"H2"であるものを、ソース上はSANSOやSUISOとして扱えるようにしました。

enum EnumGas{
 SANSO ("O2"),
 SUISO ("H2");

 String value;

 EnumGas(String value){
  this.value = value;
 }

 public String toString(){
  return value;
 }
}

enum値からデータ値への変換はEnumGas.toString()、その逆はEnumGas.valueOf()だと予測し、前者は合っていたのですが、後者は次の様な場合にIllegalArgumentExceptionとなることが判りました。

EnumGas gas = EnumGas.valueOf("H2");

"H2"ではなく"SUISO"ならばenum値が取得できるのですが、私が意図しているような"H2"からenum値 SUISOを取得するには、どうすれば良いでしょうか。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-02-19 20:23
引用:

やじゅうさんの書き込み (2007-02-19 20:06) より:
enum値からデータ値への変換はEnumGas.toString()、その逆はEnumGas.valueOf()だと予測し、前者は合っていたのですが、後者は次の様な場合にIllegalArgumentExceptionとなることが判りました。



残念ながら、前者も間違えています。
toString()はObject.toString()のオーバーライドでしかありません。
以下、JavaSE5.0のJavadocより抜粋です。
引用:

オブジェクトの文字列表現を返します。通常、toString メソッドはこのオブジェクトを「テキストで表現する」文字列を返します。この結果は、人間が読める簡潔で有益な情報であるべきです。すべてのサブクラスで、このメソッドをオーバーライドすることをお勧めします。



enumにはname()というメソッドがあります。
そして、この値はソースコード上で定義した名称が帰ります。
件のコードだと"SANSO"とか"SUISO"ですね。
このメソッドはfinalメソッドなのでオーバーライドできません。
つまり、名称は変えることができません。


引用:

やじゅうさんの書き込み (2007-02-19 20:06) より:
"H2"ではなく"SUISO"ならばenum値が取得できるのですが、私が意図しているような"H2"からenum値 SUISOを取得するには、どうすれば良いでしょうか。



簡単です。

コード:
enum EnumGas{
    O2,
    H2
}


これだけです。
名称と値が違うEnumを作る必然性はまったくありません。
同じ値を表す、別の名前のenumがあったとして、メリットはないと思いますがいかがでしょうか。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-02-19 22:18
nagiseさんが仰るとおり、enumのメンバに対して
意味のない名称や与えたり、無意味に動作を付け加えるのは微妙ですね。
ここら辺は設計思想の問題でもあり、正解というのはありませんが・・・

できないか、というと別の話なので以下のように対応することも出来ます。
コード:
public enum Test {

	FUGA("fuga"),

	HOGE("hoge"),

	PIYO("piyo"),

	;

	public static Test getTest(String name) {
		for (Test test : Test.values()) {
			if (test.name.equals(name)) {
				return test;
			}
		}

		return null;
	}

	private String name;

	private Test(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return name;
	}
}


やじゅう
常連さん
会議室デビュー日: 2005/08/10
投稿数: 34
お住まい・勤務地: 野獣の住処
投稿日時: 2007-02-20 10:22
> enum EnumGas{
> O2,
> H2

すみません、例えが悪かったです。実際のデータでは "0E"とか"S1"と言った、人間にとって判りづらい文字列(電文中に存在する○○区分等)なのです。

> public static Test getTest(String name) {
> for (Test test : Test.values()) {

なるほど、for文でナメるワケですね。
皆さんのご指導を吟味しながら、検討してみます。
ありがとうございました。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-02-20 13:54
引用:

やじゅうさんの書き込み (2007-02-20 10:22) より:
すみません、例えが悪かったです。実際のデータでは "0E"とか"S1"と言った、人間にとって判りづらい文字列(電文中に存在する○○区分等)なのです。



はは〜ん。なるほど。そういう事例では確かに分かりやすい名前でEnum化したいでしょうし、
区分のIDとEnum値との相互変換もしたいことでしょうね。

数が十分に少ないのであればforでまわしてもよいでしょうが、
ある程度多いのであればMapでkeyをID値にvalueをEnumにして管理するのがよいのではないでしょうか。
非常に多い場合などはDBなどの外部ストレージで管理するのが通常ですね。
DB管理になっちゃう場合はEnumでは扱えませんね。
1

スキルアップ/キャリアアップ(JOB@IT)