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

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

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

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

Q&A

解決済

3回答

3289閲覧

リフレクション 文字列配列でのエラー java

sanezane

総合スコア91

Java

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

0グッド

1クリップ

投稿2018/01/27 14:39

編集2018/01/28 04:13

スッキリjavaの練習問題です。配列の非常にシンプルなエラーなのですが(画像左下)コードが長くなると、どこを修正すればよいのかがわかりません。実践編になって難易度がグッと上がり挫折しそうになりながらも進めています。最後にある2通りの起動を試す方法もイマイチわかりません。少々長いですがどうか助けてくださいお願いします。
クラスの条件:
1.コマンドライン引数から、次の2つの情報を受け取る
・第一引数…起動すべきクラスのFQCN
・第二引数…起動仕方を示す文字。EまたはI
2.現在のメモリ使用量を表示する
3.FQCNのクラスが持つ、すべてのメソッド名を画面に表示する
4.FQCNのクラスが、文字列配列の引数を持つpublicメソッドmain()を持つか調べ、もし持っていれば、コマンドライン第二引数によって次のように起動する。
・Eの場合…ProcessBuilderで別プロセスとして起動する
・Iの場合…リフレクションでmainメソッドを呼び出す
5.現在のメモリ使用量(MB単位)を表示する
6.このプログラムが終了する際には、起動に成功した場合は0、そうでなければ1を終了コードとする。

また、起動すると要素数1280000のlong型配列を確保するだけの処理を行うプログラムMemoryEaterを作成し、Launcherで2通りの起動を試してください。

import java.lang.reflect.Method; public class Launcher { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ System.out.println("eating memory..."); long[] larray = new long[1280000]; for(int i = 0;i<larray.length;i++) { larray[i] = i; } //コマンドライン引数(main関数に渡す引数)//argsは文字列配列として扱われる String fqcn = args[0]; //条件①起動すべきクラスのFQCN(完全限定クラス) String sw = args[1]; //起動仕方を示す文字EまたはI showMemory(); try { Class<?> clazz = Class.forName(fqcn);//クラスインスタンスを取得 listMethods(clazz); if(sw.equals("E")) { launchExternal(clazz); //"E"の場合ProcessBuilderで別プロセスとして起動する }else if(sw.equals("I")) { //定義は後ろ launchInternal(clazz); //"I"の場合リフレクションでmainメソッドを呼び出す //定義は後ろ }else { //EとI以外はエラーを投げる throw new IllegalArgumentException("起動方法の指定が不正です"); } }catch(Exception e) { //EとIでのエラー発生時 System.out.println(e.getMessage()); e.printStackTrace(); System.exit(1); //0以外は異常終了 } showMemory(); System.exit(0); } //③すべてのメソッド名を画面に表示する public static void listMethods(Class<?> clazz) { System.out.println("メソッドの一覧を表示します"); Method[] methods = clazz.getDeclaredMethods();//Methodオブジェクトが格納された配列を返す for(Method m : methods) { System.out.println(m.getName()); //Methodの名前をStringとして返す } } //launch external(外部起動)メソッドの実装 public static void launchExternal(Class<?> clazz) throws Exception{ ProcessBuilder pb = new ProcessBuilder("java",clazz.getName()); Process proc = pb.start(); proc.waitFor();//プロセス終了まで現在のスレッドを待機させる } //launchInternal(内部起動)メソッドの実装 public static void launchInternal(Class<?> clazz) throws Exception{ Method m = clazz.getMethod("main", String[].class); String[] args = {}; m.invoke(null, (Object)args);//静的メソッド呼出し時は第一引数は何を指定しても良い //Object..可変長引数に配列を渡す場合はObject型へのキャストが必要 } //現在のメモリ使用量を表示するshowMemory()の実装 public static void showMemory() { long free = Runtime.getRuntime().freeMemory();// long total = Runtime.getRuntime().totalMemory(); long usage = (total - free)/1024/1024; //MBへ変換 System.out.println("現在のメモリ使用量:" + usage + "MB"); } }

イメージ説明

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

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

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

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

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

guest

回答3

0

自己解決

eclipseでの実行時に起動引数 MemoryEaterとEもしくはIを入れて実行したところ無事に実行できました。
みなさんお騒がせしました。

投稿2018/01/28 09:34

sanezane

総合スコア91

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

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

0

画像では「13行目でArrayIndexOutOfBoundsExceptionが発生している」ことはわかったのですが、
肝心の13行目がコメント行になっており、こんなエラースタックトレースは発生するはずがありません。
エラーが発生してから何かコードをいじりませんでしたか?

投稿2018/01/28 02:11

swordone

総合スコア20651

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

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

sanezane

2018/01/28 03:57

そうですね。すみません!おそらく13行目を見ているときにその辺りをイジッてしまったのかと思います。 画像で言うと14行目のargs[0]が範囲外エラーになっていると思います。
swordone

2018/01/28 04:06

そのことを確認するためにも、改めてその状態で実行してみてスタックトレースを出してみてください。
sanezane

2018/01/28 04:15

実行してみたところやはり14行目でArrayIndexOutOfBoundsExceptionとなりました。画像の差し替えを実施したのでご確認お願いします。
guest

0

訂正&お詫び:
「コードがテキストにて提示されてなく、スクリーンショットのみではわかりにくい」と指摘したのですが、自分の見落としでした。

そのような間違いをおかしたコメントについて質問者さんや閲覧者の皆さんは「気持ち的にも」受け入れがたいと思います。穴があったら入りたい気持ちです。質問自体を削除したいですが、あえて恥をさらしておきます。

大変失礼いたしました。


すみませんが、回答ではありません。

  • スクリーンショットでコードを貼ること

あなたには簡単なのかも知れませんが、閲覧者には見ずらいです。コピペすることもできません。
手間を惜しまずteratailのマークダウンの使い方をちゃんと調べてテキストとしてコードを質問文に提示することをお奨めします。

参考:下記ページの「コードを入力」のところにあるマークダウン
https://teratail.com/help#about-markdown

  • 何がわからないのでしょう?

色々書いておられますが、あなたに何がわからないのかのポイントが曖昧すぎるように思います。プログラムの全部の仕様を提示する必要があるのでしょうか?わからない点に限ってその部分だけのコードを提示し、「どこがわからない」と書いた方がずっと分かり易い質問になると思います。

問題文全体を提示して「自分が書いたコードのどこが間違っているか教えて」とか「その仕様を全て満たすコードを教えて」っていうのは丸投げ質問あるいはそれに近いものを感じます。

投稿2018/01/27 15:55

編集2018/01/28 02:27
KSwordOfHaste

総合スコア18394

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

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

sanezane

2018/01/27 16:17

わかりずらくて申し訳ございません。現状このコードで実行するとException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0という内容のエラーが発生するのです。コードのargs[0]のところで引っかかっているのかはわかるのですが、それをどうすればいいのかで止まってしまい、すべてのコードと条件を載せてしまった次第です。
KSwordOfHaste

2018/01/27 16:32

えと・・・質問をよく見直してみてください。「実行するとArrayIndexOutOfBoundsException例外が発生して困っている。その原因を知りたい」とは全然書いてありません。何を知りたいかを明確に書いてもらえれば「それは引数を渡してないからだと思う」と答えられたのですが・・・ 引数が渡ってない原因はおそらくeclipseの実行のコンフィギュレーションに引数を指定してないからだと思いますけど・・・
swordone

2018/01/28 02:09

コードは最初から質問に書かれてましたよ。画像の上に
KSwordOfHaste

2018/01/28 02:12

大変失礼しました!回答取り消します。 早とちりにもほどがあります・・・
sanezane

2018/01/28 04:04

KSwordOfHasteさん いえいえ!実際、自分でも的確な質問ができているとは思いませんので...args[0]を修正すべきか、他を修正すべきかがわからないので全てのコードを載せました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問