普通の enum
普通に enum 定義して、
package foo; public enum Operation { PLUS, MINUS, ; }
クラス名を取得すると以下となる。
Operation.PLUS.getClass().toString(); // -> "class foo.Operation" Operation.PLUS.getClass().getSimpleName(); // -> "Operation" Operation.PLUS.getClass().getCanonicalName() // -> "foo.Operation"
enum を画面表示用の文字列に変換する場合のキーとして getSimpleName()
と enum値のtoString()
を使ったりすることはよくあるケース。
Strategy enum パターンにすると
タイプ別で振るまいを変えたい場合には Strategy enum パターン がよく使われる。
TimeUnit
なんかと同じですね。
package foo; public enum Operation { PLUS(){ @Override public double apply(double x, double y) { return x + y; } }, MINUS(){ @Override public double apply(double x, double y) { return x - y; } }, ; // ・・・ public abstract double apply(double x, double y); }
当然ながら、各enumは匿名クラスになっているため
Operation.PLUS.getClass().toString(); // -> "class foo.Operation$1" Operation.PLUS.getClass().getSimpleName(); // -> "" Operation.PLUS.getClass().getCanonicalName(); // -> null
getSimpleName()
は空文字、getCanonicalName()
は null となる。
どちらでも同じ結果を得たい場合には
以下のように EnclosingClass
で判断できる。
Operation operation = Operation.PLUS; String name = (operation.getClass().getEnclosingClass() != null) ? operation.getClass().getEnclosingClass().getSimpleName() : operation.getClass().getSimpleName(); assertThat(name).isEqualTo("Operation");
その他についても同じ。
Operation operation = Operation.PLUS; Class<?> enclosingClass = operation.getClass().getEnclosingClass(); if (enclosingClass != null) { assertThat(enclosingClass.toString()) .isEqualTo("class foo.Operation"); assertThat(enclosingClass.getSimpleName()) .isEqualTo("Operation"); assertThat(enclosingClass.getCanonicalName()) .isEqualTo("foo.Operation"); } else { assertThat(operation.getClass().toString()) .isEqualTo("class foo.Operation"); assertThat(operation.getClass().getSimpleName()) .isEqualTo("Operation"); assertThat(operation.getClass().getCanonicalName()) .isEqualTo("foo.Operation"); }
過去3回ぐらい遭遇した。 注意しましょう。