- - PR -
NoSuchMethodExceptionの原因
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-11-28 22:34
いつもお世話になります。
任意のクラスのメソッドを呼び出すクラスAを作成しましたが、 クラスBの引数がConnection型のメソッドを呼び出すと、下記コードの"エラー"の箇所で parClass[0].getConstructor(new Class[] {Class.forName( "java.sql.Connection" ) })が "java.lang.NoSuchMethodException"となります。 クラスBの引数がStringなら問題なく呼び出すことができます。 java.sql.Connectionの場合なぜエラーになるのかお教えください。 ////////////////////クラスA//////////////////// Public static void rootSelect( Connection con, String key ) throws ServerException{ //keyからクラス名、メソッド名を取得 ・ ・ 省略 Class actionClass = Class.forName( クラス名 ); Constructor constructor; Object actionInstance; constructor = actionClass.getConstructor( new Class[] {} ); actionInstance = constructor.newInstance( new Object[] {} ); Class[] parClass = new Class[1]; Object[] parObject = new Object[1]; //型定義 parClass[0] = Class.forName( "java.sql.Connection" ); //値定義 parObject[0] = parClass[0].getConstructor( new Class[] {Class.forName( "java.sql.Connection" ) } ).newInstance( new Object[] { con } );------エラー Method actionMethod = actionClass.getDeclaredMethod( メソッド名, parClass ); actionMethod.invoke( actionInstance, parObject ); } ////////////////////クラスB//////////////////// public void execute(Connection con) { //省略 } | ||||||||||||
|
投稿日時: 2003-11-28 22:45
java.sql.Connectionがインタフェースだからでしょう。
| ||||||||||||
|
投稿日時: 2003-11-28 23:25
M・Fさんありがとうございます。
>java.sql.Connectionがインタフェースだからでしょう。 インターフェースだと駄目となると どうすればConnectionを引数にもつクラスBを呼べるのでしょうか。 クラスBのConnectionはjava.sql.Connectionをインポートしていますが こちらを変える必要があるのでしょうか? | ||||||||||||
|
投稿日時: 2003-11-29 01:02
すみませんが、私には提示されたソースコードから「空条Q太郎さんはもともと何がしたいのか」を読み取ることができません。まず、なぜこのようなコードを書かれたのか、そちらから教えていただけませんか?それが無いと、M・Fさんの仰るように「java.sql.Connectionがインタフェースであるから、コンストラクタを探してもNoSuchMethodと言われるのは当然である」としか答えられないのです。
| ||||||||||||
|
投稿日時: 2003-11-29 10:22
クラスAのrootSelectメソッドで、任意のクラスBをインスタンス化してConnectionを引数に持つexecuteメソッドを呼び出したいと解釈すると、
Class actionClass = Class.forName("ClassB"); actionInstance = actionClass.newInstance(); Class[] parClass = new Class[]{java.sql.Connection} Method actionMethod = actionClass.getMethod("execute", parClass); Object[] parObject = new Object[]{con} actionMethod.invoke( actionInstance, parObject ); のような感じでいいのではないでしょうか? #すみませんが時間がない為コードの検証はしてません。例外処理も省いています。 [ メッセージ編集済み 編集者: M・F 編集日時 2003-11-29 10:23 ] | ||||||||||||
|
投稿日時: 2003-12-01 13:09
おばけさん、M・Fさんご回答ありがとうございました。
遅くなりました、すみません。 おばけさんの >「空条Q太郎さんはもともと何がしたいのか」 については、M・Fさんからの >クラスAのrootSelectメソッドで、任意のクラスBをインスタンス化してConnectionを引数に持つ >executeメソッドを呼び出したいと解釈すると、 です。詳しくはConnectionを引数に持つ幾つかのクラスがあり、クラスAのrootSelectメソッドの keyに該当するクラスのメソッドを呼び出したいのです。 また >M・Fさんの仰るように「java.sql.Connectionがインタフェースであるから、コンストラクタを >探してもNoSuchMethodと言われるのは当然である」としか答えられないのです。 コンストラクタのないjava.sql.ConnectionでgetConstructorメソッドは当然駄目ですね。すみません。 最終的なソースは以下の通りです。 ////////////////////クラスA//////////////////// Public static void rootSelect( Connection con, String key ) throws ServerException{ //keyからクラス名、メソッド名を取得 ・ ・ 省略 //クラスオブジェクト作成 Class actionClass = Class.forName( クラス名 ); //コンストラクタオブジェクト作成 Constructor constructor = actionClass.getConstructor( new Class[] {} ); //インスタンス作成 Object actionInstance = constructor.newInstance( new Object[] {} ); Class[] parClass = new Class[1]; Object[] parObject = new Object[1]; //型定義 parClass[0] = Class.forName( "java.sql.Connection" ); //値定義 parObject[0] = con; Method actionMethod = actionClass.getDeclaredMethod( メソッド名, parClass ); actionMethod.invoke( actionInstance, parObject ); } ////////////////////クラスB//////////////////// public void execute(Connection con) { //省略 } | ||||||||||||
|
投稿日時: 2003-12-01 13:47
なるほど、なんとなく分かってきました。
「Connectionを引数に持つ幾つかのクラス」というのは、「Connectionを引数に取るexecuteというメソッドを持つ幾つかのクラス」という意味ですか?
そもそも、インタフェースにはコンストラクタは無いのです。 ところで、このコード、もっと簡略化できませんか? 例えば、
というように。 あらかじめexecuteというメソッドを呼び出すことも決まっていますし、そのシグネチャも一つであるならば、メソッドのリフレクションを使う意義が良く分かりません。 それとも、このサンプルコードには無い部分でメソッドのリフレクションが必要なのでしょうか? | ||||||||||||
|
投稿日時: 2003-12-01 16:11
おばけさんご回答ありがとうございます。
rootSelectメソッドの引数:keyからクラス名とメソッド名を取得しようとしたためメソッドのリフレクションを使いました。 メソッド名がexecuteだけでないということです。 ただし、"excecuteに統一したほうが良い"との声もありますので おばけさんから頂きましたコードで試してみたいと思います。 勉強になりました。ありがとうございました。 | ||||||||||||
