Java数组元素复制到不同容量新数组及索引越界问题排查求助
错误诱因分析
- 字段语义混淆,缩容时未同步更新有效元素计数:你代码中命名为
capacity的字段实际存储的是已存入数组的有效元素个数,并非数组的最大容量。当调用changeCapacity传入的新容量小于当前已存入的有效元素数量时,Arrays.copyOfRange生成的新数组长度仅为新容量值,但capacity字段不会同步修改,后续执行toString遍历、add插入元素时,会访问超过新数组长度的下标,直接触发数组越界错误。 bag数组错误使用static修饰:static修饰的成员属于类本身而非类实例,如果你创建多个IntBag2对象,所有对象会共享同一个数组,任意对象修改数组内容都会影响其他所有对象,属于逻辑设计错误。- 容量调整逻辑缺失参数校验:当前
changeCapacity方法没有对输入的新容量做合法性校验,传入负数、0等非法值时会直接触发Arrays.copyOfRange的参数异常。
修复代码示例
import java.util.Scanner; import java.util.Arrays; public class IntBag2 { private static final int INITIAL_SIZE = 20; // 移除static修饰,每个实例持有独立数组 private int[] bag; // 重命名为size,明确语义:存储已存入的有效元素个数 private int size; public IntBag2() { bag = new int[INITIAL_SIZE]; } public IntBag2(int initCapacity) { if (initCapacity <= 0) { throw new IllegalArgumentException("初始容量必须大于0"); } bag = new int[initCapacity]; } public boolean add(int item) { if (size == bag.length) return false; bag[size++] = item; return true; } public void changeCapacity(int newCapacity) { if (newCapacity <= 0) { throw new IllegalArgumentException("新容量必须大于0"); } // 新容量小于当前有效元素数时,截断有效元素计数,避免越界 if (newCapacity < size) { size = newCapacity; } bag = Arrays.copyOfRange(bag, 0, newCapacity); } @Override public String toString() { String result = "Bag: "; for (int i = 0; i < size; i++) result += bag[i] + " "; return result; } public static void main(String[] args) { Scanner input = new Scanner(System.in); IntBag2 intBag = new IntBag2(); boolean done = false; while (!done) { System.out.println("1. Add an Item to the Array"); System.out.println("2. Change Length of Array"); System.out.println("3. toString"); switch (input.nextInt()) { case 1: System.out.println("Add an Item to the Array"); intBag.add(input.nextInt()); break; case 2: System.out.println("Change Length of Array"); intBag.changeCapacity(input.nextInt()); break; case 3: System.out.println("toString"); System.out.println(intBag.toString()); break; } } input.close(); } }
内容的提问来源于stack exchange,提问作者user16854661
相关产品推荐
相关产品推荐

