Java:数组中的索引存在,ArrayIndexOutOfBoundsException:0

对不起,如果这是回答某处,因为我错过了一些明显的东西,但我已经使用Google这几天了,这似乎没有任何意义。 我有3年的JavaScript经验,现在正在进入Java,所以我没有落后于任何事物的基本概念。

我为此使用IntelliJ,但它没有指出问题。 我的类之间的通信(访问权限和实例化)是好的,代码语法和variablestypes等,所以我真的不知道它是什么。

我有一个数据类,只保存“只读”数据的其他类使用。

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]; } } 

规格数组本身包含定义的数据(即数组不为空),x作为规格数组的索引(即0 <= x <= 3)是有效的,其types为int,Test具有对specs数组(全部使用debugging输出语句确认)。 然而,当它试图设置范围的值(那么,那么,在那个确切点),我得到了“指数越界”的错误。

有人可以告诉我什么是错误的,当试图读取数组? 或者我正确地说这真的很奇怪,我需要发布整个代码?

注意:一个小的新testing也表明,如果我改变代码首先从数组中输出一个手动select的值,然后设置范围的值,控制台打印错误语句(并退出程序),然后按照打印手动拾取的值,但分配值,然后要求输出范围只会引发错误…这绝对没有意义!

编辑:我编辑了上面的代码。 名为Test的类在我的代码中叫做Soldier(我正在制作一个基于文本的游戏…)。 下面的堆栈跟踪,如果没有完整的代码(这是很长的时间)没有任何好处。 我的程序的基本结构是这样的:

1)Boot包含主要方法并实例化一个新游戏

2)游戏实例化x个团队

3)每个团队实例化一个军队

4)每个军队实例化x个士兵

每个类的实例都被设置为实例化类的属性(public Army army;例如,在Team构造函数中有一个Army实例化)。 它实质上是一系列构造函数实例化后续类,并将它们分配为它们的属性。

 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 

编辑编辑:这是半完整的代码(我遗漏了与它无关的东西,包括import)。 这是没有特定的顺序,并在IntelliJ项目内的单独的.java文件中的类。 游戏继续进行,直到新士兵要求指定其types(执行用户input的function正在正常工作,并validationinput,如同技术上相同的其他游戏部分所certificate的那样)。

 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."); } } 

问题出在您的Army班上:

 public static Object[] soldiers = new Object[] {}; 

您初始化一个名为soldiers的空(长度== 0)数组,但稍后访问:

 soldiers[soldiers.length] = new Soldier(this); 

这导致失败。

根据定义, soldiers.length长度超出了数组的界限(因为界限从0soldiers.length-1长度soldiers.length-1


为了克服它 – 确保你在阵列soldiers分配足够的空间,或者使用动态数组( ArrayList )来代替。 您可以使用ArrayList.add()将元素附加到ArrayList ,并且在填充之前不需要知道预期的大小。

x应该大于-1且小于4。

堆栈跟踪没有提到Solder类,它在陆军类的构造器中。

任何如何,只要知道该指数应该在一个范围内是不够的。 作为程序员,您有责任在尝试访问该索引处的元素之前验证索引。

 if(index > 0 && index < array.length) { //then only acess the element at index 

问题是阵列战士的大小为0。

这行int x = ...; // user input int x = ...; // user input意味着你正以某种方式从用户那里接受输入,并用它来访问数组。 你检查这个值是否在范围内(即0到3之间)? 如果没有,这可能是你测试的原因。

编辑:这样的事情可能会为你解决:

 public class Army { public Team team; public Vector<Soldier> soldiers; public Army(Team p) { soldiers = new Vector<Soldier>() team = p; for (int i = 0;i < team.game.settings.xsoldiers;i++) { soldiers.add(new Soldier(this)); } } } 

根据你的其他代码判断,这种模式在你的Game对象中也是有用的。