ネストしたenumへのリフレクションによるアクセス

このQ&Aのポイント
  • GameクラスのネストしたenumであるGameStateにJUnitのテストコードからアクセスする方法について質問です。
  • GameStateがprivateで宣言されているため、リフレクションを使用してアクセスする方法を知りたいです。
  • テストコードからGameStateにアクセスする方法を教えてください。
回答を見る
  • ベストアンサー

ネストしたenumへのリフレクションによるアクセス

public class Game {   // ゲームの状態   private enum GameState{    TITLE,    PLAYING,    GAMEOVER,   }   private GameState state; } 上記のクラスに対して、JUnitのテストコードから、 メンバ変数のstateの値とenum定数 GameState.TITLEとの比較がしたいと思っています。 イメージとしては、 if(state == GameState.TITLE){ ..... } のような形です。 GameStateがprivateで宣言されているため、テストコードからはリフレクションを使用すればアクセスできるのではないかと思っているのですが、ネストしたクラスにどのようにアクセスすればよいのかがわかりません。 テストコードにて、 Game game; Class<? extends Game> c = game.getClass(); // GameState取得 Field e = c.getDeclaredField("GameState"); とすると、実行時にGameStateがないと言われてテストに失敗してしまします。 テストコードからGameStateにアクセスするにはどのようにすればよいのでしょうか?

  • Java
  • 回答数3
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • vaguechat
  • ベストアンサー率85% (47/55)
回答No.3

enumなのでClass#getEnumConstants()でenumクラスの要素の配列を得る方がシンプルか…… 要素の特定は、宣言した名前を返すname()で返ってくる文字列と比較するか、 宣言順を変えることがないのならインデックスで指定(TITLEなら0)してもいいかも。 どちらにしてもGameStateという名前は使えないのでObjectとして受けて精々Enumにキャストするくらいしかないのは変わらない。 Object[] game_gamestate = null; for (Class cls : Game.class.getDeclaredClasses()) { if (! "GameState".equals(cls.getSimpleName())) continue; game_gamestate = cls.getEnumConstants(); break; } Object game_gamestate_title = null; for (Object o : game_gamestate) if (((Enum)o).name().equals("TITLE")) game_gamestate_title = o; または Object game_gamestate_title = game_gamestate[0];

hiropon_su
質問者

お礼

こちらのコードを参考にして、無事テストに成功しました。 大変勉強になりました。ありがとうございます。

その他の回答 (2)

  • vaguechat
  • ベストアンサー率85% (47/55)
回答No.2

> // Game.GameStateクラス内で定義されたTITLEというGame.GameState型の静的変数への参照を得る。 正確には、 // Game.GameStateクラス内で定義されたGame.GameState型の静的変数TITLEに代入されているインスタンスへの参照を得る。 でした。

  • vaguechat
  • ベストアンサー率85% (47/55)
回答No.1

Game.GameStateクラスはGameクラスのメンバーではあるがフィールドではない。 したがって、 > c.getDeclaredField("GameState"); では必要としているものを得ることはできない。 特にJUnit用のテストコードを書いたりはしないが、大雑把なサンプルを以下に示す。 import java.lang.reflect.Field; public class GameTest { public static void main(String[] args) throws Exception { // Game.GameStateクラス内で定義されたTITLEというGame.GameState型の静的変数への参照を得る。 Object game_gamestate_title = null; for (Class<?> cls : Game.class.getDeclaredClasses()) { // メンバーとして定義されたクラスのリストから if (! "GameState".equals(cls.getSimpleName())) continue; // GameStateでなければ無視 game_gamestate_title = cls.getDeclaredField("TITLE").get(null); break; } // Gameクラス内で定義されたstateというフィールドのFieldインスタンスを得る。 Field game_state = Game.class.getDeclaredField("state"); game_state.setAccessible(true); // privateフィールドへのアクセスに必要 // Gameインスタンスを生成しこれを使い何かを何かする。 Game game = new Game(); //... gameを使って何かを何か // この時点でのstateの内容を得てGame.GameState.TITLEであることを表明する。 Object state = game_state.get(game); assert(state == game_gamestate_title); } } java -ea GameTestで実行すればstateがGame.GameState.TITLEでなければAssertionErrorを吐く。

関連するQ&A

  • 静的メンバ、ネストクラス、enumのアクセス

    下記のコードを試した所、(1)(4)は無事動作しますが、 (2)と(3)はコンパイルエラーになってしまいます。 初め、静的メンバの場合はnullでも動作する事にすごい驚いたんですが、 どこまでなら問題なく動作するかのラインがわからなくてこまっています。もしよろしければアドバイスをよろしくお願いします。 class Test{ static String A="A"; static class B{ static String val = "B"; } enum C{A,B,C} } enum D{A,B,C} class Sta{ public static void main(String[] args){ Test y=null; D y2 = null; (1)System.out.println(y.A); (2)System.out.println(y.B.val); (3)System.out.println(y.C.A); (4)System.out.println(y2.C); }}

  • VC++/MFCでリフレクション

    Javaでは、ObjectのgetClass()でClassクラスの インスタンスが取れ、実行時に指定した、メソッド名や、引数で、動的にメソッドを呼びだすようなリフレクション機能が使用できます。 同様のことをC#でも実装したことがあります。 VC++/MFCにて、このようなリフレクションをやるやり方を教えてください。 C++の標準あるいわ、MFCの機能など、どちらでもよいです。 メタクラス型のようなものを実行時に取得して、リフレクションする方法だと思います。 質問の内容はVC++.NETやVC++/CLIではないです。そちらのほうでのやり方は既に発見しました。

  • JUnitでのプライベートメソッドのテストについて

    JavaSE6で開発をしております。 eclipse3.6を用いて、JUnit3でテストを行っているのですが、 クラスのプライベートメソッドをテストするにはリフレクション以外の方法はないのでしょうか。 リフレクションを使う方法ですと、テストコードが複雑になりがちで、publicメソッドに比べると、テストするのがしんどいです。 JUnit3に限らない、他のテストフレームワークでも構いませんので、プライベートメソッドをテストする、よい方法はないものでしょうか。

    • ベストアンサー
    • Java
  • enumをintとして扱う必要があるパターンはあるのでしょうか。

    enumをintとして扱う必要があるパターンはあるのでしょうか。 よく enum ENUM_SAMPLE {  A,  B,  C, }; class CLASS_SAMPLE { private:  int type; // ENUM_SAMPLEのA,B,Cしか入らない public:  int GetType(){ return type; } }; という記述を良く見かけます。 class CLASS_SAMPLE { private:  ENUM_SAMPLE type; // ENUM_SAMPLEのA,B,Cしか入らない public:  ENUM_SAMPLE GetType(){ return type; } }; のほうが良いのではないか思うのですが、intで定義することによる利点が何かあるのでしょうか。 あと、過去に // bcc利用時に問題があるのでintに変更しました int CLASS_SAMPLE::GetType {  return type; } というコメントがついたソースを見たことがあり、 自分でbccを使ってenumを返すように修正してテストしてみたことがあるのですが、何が問題なのか見つけることが出来ませんでした。 enum名を直接使用した場合に問題が発生することがあるのか、またどのような問題が発生することがあるのか、回答お願いします。

  • リフレクション

    リフレクションによって、Stringの値(strVal)を各クラスのオブジェクトに変換したいと思っております。 下のようなコードで、this.typeにセットしてあるオブジェクトのvalueOfメソッドを実行したいのですが、clazz.getMethod部分で次のようなExceptionが発生してしまいます。 staticメソッドはgetMethodでは取得・実行できないのでしょうか? ご存知の方いらっしゃいましたら、教えて頂けないでしょうか。 【Exception】 java.lang.NoSuchMethodException: java.lang.String.valueOf() 【コード】 Class clazz = Class.forName(this.type); Method method = clazz.getMethod("valueOf", new Class[0]); return method.invoke(clazz.newInstance(), new Object[]{strVal} ); 今回、this.typeには、"java.lang.String"が入っています。

    • ベストアンサー
    • Java
  • C++でfriendクラスにしているのにprivateメンバにアクセスできない

    C++でメンバ変数をprivateにして、特定のクラスにだけ公開するようにクラスをfriend指定したのですがprivateメンバにアクセスできませんとエラーが吐かれてしまいます。 先行宣言したりもしてみたのですがどうしても使用できません。 何か心当たりのあるかた教えてください。 class A { friend class B; private: int a; }; class B { public: void test( A *a ) { a->a = 0; } }; コードは違いますがこんな感じのことをしたいのです。 /* コンソールで小さなプログラムでテストしてみると動くのにいざ実際のソースに組み込むと動かないという奇妙な状態です。よろしくお願いします。 */

  • Java リフレクションについて

    1.リフレクションを使い、値をセット(BeanのSetterメソッドにて) 2.1でセットした値を取得するために、下記コードで取得 Method Method = Class.getMethod("getLstData"); Object obj = Method.invoke(****); 上記の****の箇所には、メソッドのあるクラスのインスタンスを渡す、 というところまでは分かりますが、newInstance()してしまうと、新しいオブジェクトになってしまうので 値が取得できません。 error>>java.lang.IllegalArgumentException: object is not an instance of declaring class どのようにすれば、値の取得が可能でしょうか。 どなたかご教授いただければと思います。 ※Java 1.5を使用

    • ベストアンサー
    • Java
  • ネストトップクラス・メンバクラスについて

    現在、SJC-P取得に向け独学でJavaの勉強中です。 ネストクラス・インナークラスについて勉強している最中なのですが、 数冊テキストを読み込んでも、web検索をしても、イマイチよくわからない・・・というのが正直なところです。 どのクラス(アウタークラス/staticインナークラス/非staticインナークラス)の、 どういうメンバ(static/非static/private/final)が、 どのクラスのどういうメンバにアクセス出来るのかが整理しきれません・・・。 わからないなりに、まとめてみたのですが、理解が不十分で、かつ、この下記の通りの理解で正しいのかどうかもわかりません。 (言葉でうまく表現も出来ていない箇所も・・) また理解すべきポイントに不足があるかと思います。 どこが正しく理解出来ているのか・どこがどう間違っているかの指摘及びその内容・理解不足の箇所・よりわかりやすい例の追加や補記など、どうかよろしくお願い致します。 ●staticなインナークラス(=ネストトップクラス)について ・アウタークラスのインスタンスなしに、staticなインナークラスのインスタンスの生成が出来る。 ・staticなインナークラスからはアウタークラスの非staticメンバを直接アクセス出来ない。 (→ただし、staticアウターメンバになら直接アクセス出来る?staticであればprivateでもアクセス可?) ・staticなメソッド内で非staticなインナークラスのオブジェクトが生成出来ない。 ●非staticなインナークラス(=メンバクラス)について ・非staticなインナークラス内にstaticなメンバを持つことは出来ない。 ・アウタークラスのインスタンスを生成してからでないと非staticなインナークラスのインスタンスは生成出来ない。 ・アウタークラスの非staticメンバ及びstaticメンバに直接アクセス出来る。 ●アウタークラス(=外部クラス)について ・アウタークラスのstaticメソッド内で非staticなインナークラスのインスタンスは生成出来ない。 ・非staticインナークラスのメンバ及び、staticなインナークラスのメンバにアクセス出来る。 --------------------------------------------------------- (例)処理はさておき、定義はこんな感じを思い描いております・・ class Outclass{   private int aa;   private static int bb;   private outMethod1();   private static outMethod2();   class NotStaticInner{     private int cc;     //private static int dd;//不可     private inNotStaicMethod1();     //private static inNotStaticMethod2();//不可   }   class StaticInner{     private int ee;     private static int ff;     private inStaticMethod1();     private static inStaticMethod2();   } } 参考テキスト: 『Sun Certified Programmer for Java2 Platform5.0 Exam【310-055】』のChapter11:「ネストクラス・インナークラス」 参考URL: http://wisdom.sakura.ne.jp/programming/java/java46.html

  • エラーの理由が分りません。Private' であるため…?

    データを構造体で管理したいと思って、class testclassというクラスを作成しました。 それをtest2clsssで使うと思っているのですが、次のようなエラーが出ます 'testclass.code' は 'Private' であるため、このコンテキストではアクセスできません。 ソースは次のようなものです。 Public Class testclass Dim code As String End Class Public Class test2class Private Sub testsub() Dim test As New testclass test.code = "data" '←test.codeが駄目と言われる End Sub End Class subをPublicにしても同じエラーが出ています。 エラーの意味・原因は何で、どうすれば修正できるのでしょうか? よろしくお願いします。

  • リフレクション Method.invoke() 時のインスタンス変数

    現在リフレクションAPIを使用してフレームワークを 使いやすく構築しようとしているのですが、 以下の例の抜粋コードで、一点わからないことがあります。 1:Object bean = beanField.get(action); 2:Class<?> beanClass = bean.getClass(); 3:Method validMethod = beanClass.getMethod("valid"); 4:if (void.class.equals(validMethod.getReturnType())) { 5: // void 型 6: validMethod.invoke(bean); 7:} 6行目の invoke() で bean クラスの valid メソッドを呼び出しています。この時点でデバッグしたところ、bean が保持しているインスタンス変数に値が正常に格納されているのですが、 実際に bean.valid() メソッド内にデバッグが進んだ時、bean 内のインスタンス変数が全て null となってしまっています。 invoke したメソッド(ここではvalid)内で、自分自身(bean)のインスタンス変数値を取得することはできないのでしょうか。 invoke の引数に bean を渡しているから、取れる気がするのですが、、 お分かりになればどうかご教示ください。 以上、よろしくお願いいたします。

    • ベストアンサー
    • Java

専門家に質問してみよう