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

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

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

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

2回答

2451閲覧

getをクラスを挟んで呼び出すとエラーになってしまう

na___r

総合スコア12

Java

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2019/08/13 14:10

前提・実現したいこと

Listインターフェースを使用してMainクラス、Secondクラスから成るプログラムを作りました。
Secondクラスを更にThirdクラスに分けようとしたところで、getメソッドを複数跨いで呼び出すとエラーになってしまうことに気づきました。
もし可能であれば当初の予定通りクラス分けをしたいです、エラーになってしまう理由、またはこれを回避するよい方法などをご存知でしたらお力お貸し頂ければ幸いです。

発生している問題・エラーメッセージ

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 0 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248) at java.base/java.util.Objects.checkIndex(Objects.java:372) at java.base/java.util.ArrayList.get(ArrayList.java:458) at test.Second.getTest(Second.java:17) at test.Third.test(Third.java:8) at test.Main.main(Main.java:10)

該当のソースコード

Second.javaに作成したgetTestメソッドをThird.javaのtestメソッドで読み込み、更にそれをMain.javaで読み込んでいます。

Java

1//Main.java 2package test; 3 4public class Main { 5 public static void main(String[] args) { 6 Second second = new Second(); 7 Third third = new Third(); 8 9 second.addTest(); 10 System.out.println(third.test()); 11 } 12}

Java

1//Second.java 2package test; 3 4import java.util.ArrayList; 5import java.util.List; 6 7public class Second { 8 private List <Integer> test = new ArrayList<>(5); 9 10 public void addTest() { 11 for(int i = 1; i <= 5; i++){ 12 test.add(i); 13 } 14 } 15 16 public int getTest(int num) { 17 return test.get(num); 18 } 19}

Java

1//Third.java 2package test; 3 4public class Third { 5 Second second = new Second(); 6 7 public int test() { 8 return second.getTest(2); 9 } 10}

試したこと

Mainクラスで直接second.getTest(int num)を呼び出した場合、Secondクラス内でgetTest(int num)を呼び出すメソッドを作成しそれをMainクラスで呼び出した場合はエラーになりませんでした(つまりクラス分けさえしなければ正常に動作します)。

実際のプログラムではThird.javaのメソッド内でSecond.javaのメソッドの様々なList操作をThird.javaから行い、その全体をMain.javaで読み込む形になっているのですが、同じListのメソッドでも、addやsizeメソッドの部分ではエラーになりませんでした。

補足情報(FW/ツールのバージョンなど)

作成にはEclipseを使用しています。

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

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

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

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

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

guest

回答2

0

ベストアンサー

現状 Third class が保持している Second Instance と main()の中にある Second Instanceは別のものですよね。
なので、前者はまだListが空のままなのに、getTest(2)を呼ぶのでエラーになりますね。


回避方法としては、下記のように Instanceを渡してあげるというのがありますね。
※ ちょっとこのままだと分ける意味はあまり意味ないですが、形の上では大丈夫だと思います。
※ Javaの文法ちょっと怪しいので、イメージで捉えて下さい...

public class Main { public static void main(String[] args) { Second second = new Second(); Third third = new Third(second); // ここでinstanceを渡す second.addTest(); System.out.println(third.test()); } }
package test; public class Third { private Second second; Third(Second second) { // コンストラクタで受け取って、メンバー変数に入れておく this.second = second; } public int test() { return second.getTest(2); } }

投稿2019/08/13 14:24

mokemokechicken

総合スコア948

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

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

na___r

2019/08/13 14:40

なるほど!インスタンスについてふわっとした理解でした。言われてみれば至極納得の理由です。 addやsizeが使用できたのはただエラーを吐く要素が無かっただけでgetだけが動作していないわけではなかったんですね…… 頂いたコードを元に少し勉強して方法を模索してみます!ありがとうございます!
guest

0

作成したList(この場合test)にstaticをつけて解決致しました。
有難うございました。

投稿2019/08/14 01:07

na___r

総合スコア12

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

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

LouiS0616

2019/08/14 01:47

それは絶対に止めた方が良いです。意味が良く分かっていないなら尚更。
na___r

2019/08/14 01:56

変数にstaticをつけるとどのインスタンスでも変数が共有になるという認識だったのですが、何か危ない要素があるんでしょうか……?
LouiS0616

2019/08/14 02:04

変数を安易に共有しないというのが重要なのです。 staticフィールドは確かに便利ですが、便利が過ぎて濫用してしまいがちです。慎重に・充分に・多角的に検討した上で使って下さい。
na___r

2019/08/14 03:35

変数の共有で弊害が起こる可能性があるということでしょうか? staticについて調べたところその可否が様々なところで議論されているのですが、調べ方が不十分なのか具体的な問題点はスレッドセーフではない部分しかわからなかったので……もしマルチスレッドで処理をする可能性がある場合は使わないことを心がけるという対応で構わないのでしょうか。
LouiS0616

2019/08/14 04:39 編集

例えば、違うList系インスタンスを持ったSecondインスタンスを生成したい際に困ります。 staticで無くすとそれを前提として書いてきたコードが崩れますし、staticのまま運用するとなるとプログラマ側が考慮すべき事態が増えて手に負えなくなります。 この例に依らず、拡張あるいは修正が著しく困難になります。 mokemokechickenさんが回答で言及されているような、インスタンスを明示的に渡す方法が無難です。 staticフィールドを使う余地が全く無いわけでは無い(キャッシュの実装など)ですが、かなり限られたケースになるかと思います。 なおSecondインスタンスが単一であることが充分妥当、変更の可能性が全く無いのであれば、シングルトンにすることも考慮すべきでしょう。
na___r

2019/08/14 12:36

なるほど、つまりstaticそれ自体に危険性があるという事ではないが拡張性が制限されてしまうというデメリットがあるので、必ずしもstaticでなくとも構わない場面では安易に使用せず、他のコードを優先的に検討する方が良いということでしょうか。 目の前のプログラムの事しか考えておらず、今後の拡張性に関して全く頭にありませんでした。丁寧に教えてくださってありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問