質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

リフレクション

リフレクションとは、プログラムの実行過程でプログラム自身の構造を読み取り、編集する事が出来るプロセスのことを指します

Q&A

解決済

1回答

3293閲覧

スッキリわかるJava入門実践編の第7章(JVM操作とリフレクション)の練習問題の疑問

tanaka_hana

総合スコア19

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

リフレクション

リフレクションとは、プログラムの実行過程でプログラム自身の構造を読み取り、編集する事が出来るプロセスのことを指します

0グッド

0クリップ

投稿2018/10/21 07:32

編集2018/10/21 08:34

###練習問題の内容
以下のようなLauncherクラスを作るのが練習問題です。(一部省略)
0. 番号リストコマンドライン引数から、次の2つの情報を受けとる。
・第一引数・・・起動すべきクラスのFQCN
・第二引数・・・起動の仕方を示す文字。EまたはI
0. FQCNのクラスが、文字列配列の引数を持つpublicメソッドmain()を持つか調べ、もし持っていれば、コマンドライン第二引数によって次のように起動する。
・Eの場合・・・ProcessBuilderで別プロセスとして起動する
・Iの場合・・・リフレクションでmainメソッドを呼び出す。
0. このプラグラムが終了する際には、軌道に成功した場合は0、そうでなければ1を終了コードとする。

答えのソースコード

java

1import java.lang.reflect.*; 2public class Launcher { 3 public static void main(String[] args) { 4 String fqcn = args[0]; 5 String sw = args[1]; 6 try { 7 Class<?> clazz = Class.forName(fqcn); 8 listMethods(clazz); 9 if(sw.equals("E")) { 10 launchExternal(clazz); 11 } else if(sw.equals("I")) { 12 launchInternal(clazz); 13 } else { 14 throw new IllegalArgumentException("起動方法の指定が不正です."); 15 } 16 } catch(Exception e) { 17 System.out.println(e.getMessage()); 18 e.printStackTrace(); 19 System.exit(1); 20 } 21 System.exit(0); 22 } 23 24 public static void listMethods(Class<?> clazz) { 25 System.out.println("メソッドの一覧を表示します."); 26 Method[] methods = clazz.getDeclaredMethods(); 27 for(Method m : methods) { 28 System.out.println(m.getName()); 29 } 30 } 31 32 public static void launchExternal(Class<?> clazz) throws Exception { 33 ProcessBuilder pb = new ProcessBuilder("java", clazz.getName()); 34 Process proc = pb.start(); 35 proc.waitFor(); // プロセスの終了まで待つ 36 } 37 38 public static void launchInternal(Class<?> clazz) throws Exception { 39 Method m = clazz.getMethod("main", String[].class); 40 String[] args = {}; 41 m.invoke(null, (Object)args); // 静的メソッド呼び出し時は第一引数は任意 42 } 43}

疑問点

見出しの「練習問題の内容」の太字になっているところ。答えのソースコードのif文のあたりがその該当箇所であると思うのですが、答えのソースコードでは起動の仕方を指定しないときの対処だけしか書けていない気がします。起動したいクラスが文字列配列の引数を持つpubicメソッドmain()を持つを調べるif文が抜けていませんか。。?

まとめ

どこかにmain()を調べているコードがあれば、ぜひ教えていただきたいです。javaはまだまだですが、どうぞよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/21 08:26

listMethods の実装を削除しちゃだめよ
tanaka_hana

2018/10/21 08:28

すいません、その通りです。ありがとうございます。
guest

回答1

0

ベストアンサー

起動したいクラスが文字列配列の引数を持つpubicメソッドmain()を持つを調べるif文が抜けていませんか。。?

「調べる」という言葉の範囲の問題というのもありますが、Class#getMethodは「当該メソッドがなければ例外になる」ので、「あるかどうか調べる」ことも兼用しています。

投稿2018/10/21 08:16

maisumakun

総合スコア145062

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/21 08:23

多分これ listMethods 内部でやってる想定だけど、コード表記されてないからコンパイルエラーよ
退会済みユーザー

退会済みユーザー

2018/10/21 08:33

っとコード全文をフレアリンク社のところでみてきたらこれはひどいな。 仕様と違うからバグかもなE側の場合
tanaka_hana

2018/10/21 08:52

listMethodsを追加してみたのですが、、結局のところどこでmain()があるかの判断をしているでしょうか?そもそも文字列配列の引数を持つpublicメソッドmain()を持つかどうかを調べてから、もし持っていれば起動方法を指定するのに、launchInternal()内のClass#getMethodでは調べられていない気がするのですが。。
退会済みユーザー

退会済みユーザー

2018/10/21 09:05

I の場合は Class<E>#getMethod の場合、メソッドが存在しない例外が投げられるのでエラーとなりますが順番が仕様と違うのでバグです。 Eの場合はエラーにならない(正常終了)するのでバグですね
tanaka_hana

2018/10/21 09:16

ありがとうございます。仕様書の書き方の順序が逆であったと納得できました。 ただ、何度もすいません。。逆にEの場合エラーになると正しいのでしょうか?どうしてでしょうか?
退会済みユーザー

退会済みユーザー

2018/10/21 09:19

3の起動に成功したら0、失敗したら1に反するからエラーコードは1にならなければいけませんが0になってるはずですよ。(机上デバッグ)
tanaka_hana

2018/10/21 09:32

launchExternal()は具体的にどこがバグっているのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問