明らかな何かが欠けているためにこれがどこかで答えられた場合は申し訳ありませんが、私はこれを何日もグーグルで検索しており、意味がないようです. 私は Javascript で 3 年の経験があり、現在 Java に取り掛かっているので、何かの基本的な概念などに遅れをとっていません。
これにはIntelliJを使用していますが、問題を指摘できません。クラス間の通信 (アクセス権とインスタンス化) は問題なく、コードの構文と変数の型も同様です。
他のクラスが使用する「読み取り専用」データを保持するだけの Data クラスがあります。
public class Data {
// snip
public static int[][] specs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
初期化時にこのデータを読み取る必要がある別のクラスがあります。
public class Soldier {
// snip
public int range;
public Soldier() {
int x = ...; // user input
range = Data.specs[x][1];
}
}
specs 配列自体には、定義されたとおりのデータが含まれています (つまり、配列は空ではありません)。x は specs 配列のインデックスとして有効です (つまり、0 <= x <= 3)。その型は int で、Test はspecs 配列 (デバッグ出力ステートメントですべて確認済み)。それでも、範囲の値を設定しようとすると(そのときだけ、その時点で)、「インデックスが範囲外です」というエラーが発生します。
配列を読み取ろうとしたときに何が問題なのか誰か教えてください。それとも、これは本当に奇妙で、コード全体を投稿する必要があると言っているのは正しいですか?
注: 小さな新しいテストでは、最初に配列から手動で選択した値を出力し、次に範囲の値を設定するようにコードを変更すると、コンソールにエラー ステートメントが出力され (そしてプログラムが終了し)、次のように表示されることも示されています。手動で選択した値を出力しますが、値を割り当ててから出力範囲を要求すると、エラーがスローされるだけです...それはまったく意味がありません!
編集: 上記のコードを編集しました。Test というクラスは、私のコードでは Soldier と呼ばれています (テキストベースのゲームを作成しています...)。完全なコード (かなり長い) がなくても問題ない場合は、以下にスタック トレースを示します。私のプログラムの基本的な構造は次のとおりです。
1) ブートには main メソッドが含まれ、新しいゲームをインスタンス化します
2) ゲームのインスタンス x チーム
3) 各チームがアーミーをインスタンス化する
4) 各軍は x 兵士をインスタンス化します
クラスの各インスタンスは、インスタンス化するクラスの属性として設定されます (たとえば、パブリック Army アーミー、および Team コンストラクター内のアーミー インスタンス化)。これは基本的に、後続のクラスをインスタンス化し、属性として割り当てるコンストラクターのカスケードです。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Army.<init>(Army.java:13)
at Team.<init>(Team.java:19)
at Game.<init>(Game.java:22)
at Boot.main(Boot.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)5
編集編集:これがセミフルコードです(インポートを含め、まったく関係のないものは省略しています)。順不同で、クラスは IntelliJ プロジェクト内の個別の .java ファイルにあります。ゲームは、新しいソルジャーがそのタイプを指定するように要求するポイントまで続きます (ユーザー入力を実行する関数は正常に機能し、技術的に同一のゲームの他の部分によって証明されているように入力を検証します)。
public class Boot {
public static void main(String[] args) {
Object[] games = new Object[] {};
if (Lib.userConfirmPrompt("Start the game?") == true) {
do {
games[games.length] = new Game();
}
while (Lib.userConfirmPrompt("Do you want to play again?") == true);
}
System.exit(0);
}
}
public class Game {
public Object[] teams = new Object[] {};
public Game() {
for (int i = 0;i < settings.xbots + 1;i++) {
teams[teams.length] = new Team(this);
}
}
}
public class Team {
public Game game;
public Army army;
public Team(Game p) {
game = p;
army = new Army(this);
}
}
public class Army {
public Team team;
public static Object[] soldiers = new Object[] {};
public Army(Team p) {
team = p;
for (int i = 0;i < team.game.settings.xsoldiers;i++) {
soldiers[soldiers.length] = new Soldier(this);
}
}
}
public class Soldier {
private Army army;
public int sight;
public int range;
public int distance;
public int damage;
public Soldier(Army p) {
army = p;
int type = Lib.userTxtIntOptionsPrompt(Data.isoldiertypes);
// HERE is where it crashes, type is assigned and valid but the array access fails
sight = Data.isoldierspecs[type][0];
range = Data.isoldierspecs[type][1];
distance = Data.isoldierspecs[type][2];
damage = Data.isoldierspecs[type][3];
}
}
public class Data {
public static List isoldiertypes = Arrays.asList("Scout","Private","Machinegunner","Grenadier");
public static int[][] isoldierspecs = {
{6,1,6,40},
{5,2,5,30},
{5,3,4,40},
{4,4,3,60}
};
}
public class Lib {
private static Scanner input = new Scanner(System.in);
// output
// default: 1 query string to print
public static void outBase(String query) {
System.out.print(query);
}
public static void outStd(String query) {
outBase(query + "\n");
}
// end of output
// input
// default: 1 query string to print,
// query and input are in-line (exception: userConfirmPrompt prints query block-wise and default instruction in-line before input),
// keeps user hostage until valid input is given (exception: userPrompt returns blindly)
public static String userPrompt(String query) {
outBase(query);
return input.nextLine();
}
public static String userTxtPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userPrompt(query);
} while (menuinput.length() == 0);
return menuinput;
}
public static int userIntPrompt(String query) {
String menuinput = null;
do {
if (menuinput != null) {
userHostage();
}
menuinput = userTxtPrompt(query);
} while(menuinput.matches("^-?\\d+$") == false);
return new Integer(menuinput);
}
// end of input
// options input
// default: takes a List of options as argument,
// prints an enumerated list of these options string-wise,
// prompts for a numeral selection of the desired option and returns the number if valid
public static int userTxtIntOptionsPrompt(List options) {
int choice = 0;
Boolean chosen = false;
do {
if (chosen == true) {
userHostage();
} else {
chosen = true;
}
chosen = true;
for (int i = 0;i < options.size() - 2;i++) {
outStd((i + 1) + ") " + options.get(i) + ",");
}
outStd((options.size() - 1) + ") " + options.get(options.size() - 2) + "\nand " + options.size() + ") " + options.get(options.size() - 1) + ".");
choice = userIntPrompt("Enter the number of the option you'd like to select: ") - 1;
} while(choice < 0 || choice >= options.size());
return choice;
}
// end of options input
// miscellaneous
public static void userHostage() {
outStd("Invalid operation. Please try again.");
}
}