Javaのリフレクションを使ったコンストラクタの取得で躓いています。正解が分からない…。
あるクラスTestがあり、パラメータにクラスAしか取らないコンストラクタがあるとします。
クラスTestのコンストラクタに対し、クラスAと全く関係ないクラスCのインスタンスを渡せばコンパイルエラーになります。クラスAの派生クラスBのインスタンスであれば渡せます。これはオブジェクト指向言語なら当たり前です。
しかしリフレクションを使ってコンストラクタを得ようとすると、派生クラスを渡せるコンストラクタをどうやって取得すれば良いかわからないのです。
public class Test {
public Test(A a) {
}
}
public class A {
public A() {
}
}
public class B extends A {
public B() {
}
}
public class Main {
public static void main() {
Test obj1 = new Test(new A()); //OK
Test obj2 = new Test(new B()); //OK
Constructor<Test> cons1 = Test.class.getConstructor(A.class); //OK
Constructor<Test> cons2 = Test.class.getConstructor(B.class); //NG
Test obj3 = cons1.newInstance(new A()); //OK
Test obj4 = cons1.newInstance(new B()); //OK
//Test obj5 = cons2.newInstance(new B());
}
}
上記のようなコードがあったとします(try〜catchは省いています)。
クラスTestには、クラスAをパラメータにとるコンストラクタしかありません。従って、派生クラスBをパラメータに取るコンストラクタをくれ(=Test.class.getConstructor(B.class))と頼むと「そんなコンストラクタは無い」と例外がスローされます。
どうしてTest.class.getConstructor(B.class) としたとき、「ありません」なんだろうか?基底クラスを取るコンストラクタ(Test(A a))があるのだから、そちらを教えてくれれば良いのに…。
クラスTestには、クラスBを取るコンストラクタはないから、この動きは正しい。
とか、
基底クラスAを取るコンストラクタ(cons1)を得て、派生クラスBのインスタンスを渡せば良いだけだ。(つまりobj4を生成しているように書く)
という反論はわかるのですが、それだとせっかくのリフレクションなのに本末転倒になってしまいませんか?
クラスTestの利用者側の立場からすれば、クラスTestに、クラスAを取るコンストラクタがあるか?クラスBを取るコンストラクタがあるか?なんて知らないわけです。自分が呼び出したいコンストラクタが既にあるとわかっているなら、リフレクションなど使わずに直接呼べば良いのです…。
クラスTestのコンストラクタを全部取得して、クラスBの基底クラスを取るコンストラクタがないかどうか、全て探すしかないのでしょうか…。うーん、それはさすがに格好悪いような…。
< | 2013 | > | ||||
<< | < | 03 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | - | - | - | - | - | - |
合計:
本日: