リフレクションでフィールドのインスタンス取得

このQ&Aのポイント
  • リフレクションを使ってフィールドの型やオブジェクトのタイプ、名前などは取得できるが、それ自身のインスタンスを取得できない。
  • ClassオブジェクトのnewInstanceでは新しく作ってしまうため、目的のインスタンスを取得する方法はないのか。
  • Barからfoo1, foo2のメソッドを呼び出したいが、Fooの定義数がわからないため、リフレクションを使用してFooのClassやFieldを取得できるが、Fooのインスタンスそのものを取得したい。
回答を見る
  • ベストアンサー

リフレクションでフィールドのインスタンス取得

リフレクションを使ってフィールドの型やオブジェクトのタイプ、名前などは取得できるのですが、それ自身のインスタンスを取得できません。 ClassオブジェクトのnewInstanceでは、新しく作ってしまうのでだめでした。なにかよい方法はないでしょうか? class Parent{ Foo foo1,foo2; Bar bar; } というクラスでbarからfoo1,foo2のメソッドを呼び出したいのですが、 Fooは何個定義されるかわからない状態です。 Barないでリフレクションを使ってfoo1,foo2をあらわすClassやFieldは取得できるのですが、foo1,foo2自身が取得したいのです。 よろしくお願いします

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

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

  • ベストアンサー
  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.1

インスタンスメソッドは、インスタンスを経由する(=該当インスタンスをBarのインスタンスに渡す)以外にアクセス出来ないと思います。 Barクラスの方でコンストラクターに引数を付けるか、またはインスタンスを得るための専用メソッドを作成する必要があると思います。このときに渡したインスタンスをvisitorと呼んだりします。 デザインパターンのvisitor patternを調べてみるとよいでしょう。 個数が不定なら、配列かArrayListにして渡すというのはどうでしょう? // // 以下例文 とりあえず配列を使う方法:引数での受け取り側では長さを指定なくてもよいことに注目 class Bar{ private Foo[] fooArray = new Foo[0]; // 配列の長さを調べるときにNullPointerExceptionが発生しないようにするため長さ0で初期化。 Bar(){ // Fooの個数が確定しないときに呼ぶコンストラクター、fooArrayはまだ使えないことに注意 } Bar(Foo[] foos){ fooArray = foos; } void setFooArray(Foo[] foos){ // visitorを得るためのメソッド fooArray = foos; } void nanikasuru(){ if( fooArray.length>0){ // 中身のある配列になっているかチェックしてから作業開始 for( int i=0; i<fooArray.length; i++){ fooArray[i].fooMethod(); } } } } class Parent{ Foo foo1,foo2; Bar bar; Parent(){ foo1=new Foo(); foo2=new Foo(); } void parentMethod(){ // 配列を一括して初期化する手法を適用すれば、渡す側で個数を確定出来る bar = new Bar(new Foo[]{foo1,foo2}); bar.nanikasuru(); } } // // こんなところでどうでしょ?

matico
質問者

お礼

ありがとうございます。 FooとBarはライブラリでParentはユーザーのコードで できれば、FooとBarを定義するだけで、Fooから呼び出してくれる というのをやりたかったのですが、 インスタンスを渡すか、Listerをつけるかというのになりそうですね。 どうもありがとうございました。

関連するQ&A

  • 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
  • リフレクション

    リフレクションによって、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
  • VC++/MFCでリフレクション

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

  • privateのメソッドをリフレクションで呼び出す方法

    privateのメソッドをリフレクションで呼び出す方法 private のメソッドをリフレクションで呼び出す方法 privateのメソッドもリフレクションというもので呼び出せると聞きましたが、やり方がよく分かりません。 aaaやbbbクラスのインスタンスを生成したいのですが、privateやpackage privateのため、そのままだとインスタンスが生成できません。 forNameメソッドやnewInstanceメソッドでどうにかできないかと試してみたのですが、イリーガル例外が発生してしまいます。 何かよい方法がないでしょうか? aaa, bbbのクラスを継承してモックを作成する方法もあるのですが、今回はそういった方法ではなく、privateやpackage privateメソッド(特にコンストラクタ)を外部から呼び出す方法がよいです。 public aaa { private aaa() { } private func() { } } public bbb { aaa() { } private func() { } }

    • ベストアンサー
    • Java
  • リフレクション 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
  • リフレクション

    Webアプリ上でリフレクションにてとあるクラスのメソッドを実行するサンプルを作成して 見たのですがうまく動きませんでした。最後のmethod.invoke()の処理にてExceptionが発生し、 java.lang.IllegalArgumentException: object is not an instance of declaring class と表示されてしまいます。 作成したサンプルは下記なのですがどこが原因かお分かりになりますでしょうか。 try { Class cls = Class.forName("dao.TestDao"); // 引数の型をセット Constructor constructor = cls.getDeclaredConstructor(HttpSession.class); constructor.setAccessible(true); // 引数を渡してオブジェクトを生成 Object obj = constructor.newInstance(session); Method method = cls.getDeclaredMethod("getDataDao", int.class); method.setAccessible(true); Object result = method.invoke(cls, new Integer(100)); } catch (Exception e) { e.printStackTrace(); } // このクラスのgetDataDao()をリフレクションにて実行 public class TestDao { HttpSession session = null; public TestDao(HttpSession session) { this.session = session; } public List<String> getDataDao(int iNo) { List<String> list = new ArrayList<String>(); list.add((String)session.getAttribute("1")); list.add((String)session.getAttribute("2")); list.add((String)session.getAttribute("3")); list.add((String)session.getAttribute("4")); list.add((String)session.getAttribute("5")); return list; } }

    • ベストアンサー
    • Java
  • リフレクションでフィールドに値を設定

    リフレクションで取得したクラスの一覧の各クラスのString型のフィールドにだけ 任意の値を設定するサンプルを下記のように作成しました。 このプログラムの流れの中でString型のフィールドに任意の値を設定するには どのように書けばよいでしょうか。 調べてみるとFieldクラスのsetメソッドを使用するようですが下記サンプルの中で 第一引数には何を渡せばよいかがわからないです。 【サンプル】 ※最初のgetClasses()で指定パッケージ配下のクラスは取得できています。 import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; public class ReflectionTest { public static void main(String[] args) { List<Class<?>> classes; try { // 指定したパッケージ配下のクラスを取得 classes = getClasses("test"); for (Class<?> class1 : classes) { Field[] fields = class1.getDeclaredFields(); for(Field field : fields) { field.set(????, "任意の文字列"); // 第一引数に何を渡せばよい?? System.out.println(field.getType().getName()); } } } catch (ClassNotFoundException | IOException | URISyntaxException e) { e.printStackTrace(); } } }

    • ベストアンサー
    • Java
  • リフレクション 可変長引数メソッドの取得

    リフレクションで、(1)の方のメソッドインスタンスを得たいとき、どういった方法が考えられますか? //JDK 6.0 public Hoge { void method1(String str, Object ...objs){}//(1) void method1(String str, String str2){}//(2) } Hoge hoge = new Hoge(); Class c = hoge.getClass(); Method m12 = c.getMethod("method", String.class, String.class); Method m11 = c.getMethod("method", ?? );

    • ベストアンサー
    • Java
  • サブクラスで.newInstance()でインスタンス化できない

    以下のようにClass.forNameで取得したクラスをインスタンス化 しようとしていますが、できません サブクラスは.newInstance()でインスタンス化できないのでしょうか? 代替の方法はありますか? ーーーーーーーーーーーーーーーー public class test4121 { public static void main(String[] args) throws Throwable { new test4121(); } public test4121() throws Throwable { //これは実行できるが test4121_2 test = new test4121_2(); //これはできない Class.forName("test4121$test4121_2").newInstance(); } class test4121_2{ } } ーーーーーーーーーーーーーーーー

  • Ruby 特異メソッドのnewが先に実行?

    Rubyのインスタンス生成について質問があります。 通常クラスを定義する場合は class Hoge ; def hello(); pirnt "hello"; end であると思います。 ただ Hoge = Class.new(); でもクラスは定義できるとききました。 ただこの場合Hogeクラスに定義できるのは HogeというClassクラスから作られた特異クラスとしてのHogeに 特異メソッドのみを定義できるということですよね? 通常のインスタンスメソッドは定義できませんよね? ではでは、 hoge = Class.new(); とした場合はどうなるのでしょうか? この場合は Classクラスの純粋なインスタンスとなるのでしょうか? 前者の定義とおなじ仕方ですが代入先が、通常の変数です。 この場合は、クラスオブジェクトとして生成されるのですか? オンラインマニュアルをみたところ 「新しく名前の付いていない superclass のサブクラスを生成します。 superclass が省略された時にはObject のサブクラスを生成します。 名前のないクラスは、最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。」 とあります。 上記内容は Classクラスの特異クラスとして定義されている特異メソッド(new)です。 これは Class.new()で作られたインスタンスを代入する先が定数であればその定数名と同じクラスを定義しつつそのClassクラスのクラスオブジェクトを生成するという意味合いでまちがいないでしょうか? 上記のとおりであれば hoge =Class.new()の場合は、やはりhogeというクラスを定義することになるのでしょうか? クラス定義は定数でなければならないはずですよね。 ただ実際、 p hoge;として出力すると#とひょうじされています。これはhogeがクラスオブジェクトではなく ただのインスタンスであるということでしょうか? であるならばこの hoge = Class.new()の式のnewはClassクラスオブジェクトに定義された特異メソッドではなく Classクラスに定義されたnewメソッド・・・・・つまりClassクラスに定義されたインスタンスメソッドの方のnewメソッドだとおもうのですが・・・・・・。 つまりこちらのメソッドですね。 「new( ... ) クラスのインスタンスを生成して返します。このメソッドの引数はブロック引数も含め initialize に渡されます。」 ※オンラインリファレンスから参照しました。 しかし 通常メソッドの検索は特異メソッドからはじまりその後クラスのインスタンスメソッド->親クラスのメソッドと 検索して行くとあります。 必ず先に、特異メソッドを実行しているはずだと思うのですが・・・。 やはり特異メソッドnewを実行しているのでしょうか? 長々すみませんが、ご教授ください。

    • ベストアンサー
    • Ruby

専門家に質問してみよう