
本文讲解如何避免硬编码索引、安全遍历二维数组并调用方法,重点推荐面向对象重构(如 shipimage 类 + 集合)替代易错的多维数组嵌套循环。
本文讲解如何避免硬编码索引、安全遍历二维数组并调用方法,重点推荐面向对象重构(如 shipimage 类 + 集合)替代易错的多维数组嵌套循环。
在原始代码中,String[][] ships = {{"Bismarck.png","Rodney.png"},{"170", "50"},{"20", "220"}} 采用“按列组织”的二维结构(即每行代表一种属性:文件名、宽度、高度),但后续循环 for(int i = 0; i 行索引使用——这会导致 ArrayIndexOutOfBoundsException,因为 ships 只有 3 行(ships.length == 3),而 ships[0].length == 2,当 i >= 3 时访问 ships[i][*] 必然越界。
更本质的问题在于:二维字符串数组缺乏语义约束,极易引发索引错位、类型混淆和维护困难。例如,ships[1][0] 是宽度 "170",但开发者需凭记忆确认其含义;添加新战舰时需同步修改三行,稍有不慎就会导致数据错位。
✅ 推荐方案:面向对象重构(首选)
定义清晰的数据载体类,将图像信息封装为独立实体:
public class ShipImage {
private final String fileName;
private final int width; // 直接使用 int,避免运行时解析
private final int height;
public ShipImage(String fileName, int width, int height) {
this.fileName = fileName;
this.width = width;
this.height = height;
}
// Getter 方法(必要时可添加)
public String getFileName() { return fileName; }
public int getWidth() { return width; }
public int getHeight() { return height; }
}
在主类中使用 List
import java.util.*;
List<shipimage> shipImages = new ArrayList();
shipImages.add(new ShipImage("Bismarck.png", 170, 20));
shipImages.add(new ShipImage("Rodney.png", 50, 220));
BattleScene scene = new BattleScene(shipImages);</shipimage>
BattleScene 类随之简化为:
public class BattleScene {
private final List<shipimage> shipImages;
public BattleScene(List<shipimage> shipImages) {
this.shipImages = Objects.requireNonNull(shipImages);
}
public void createScene() {
for (ShipImage ship : shipImages) {
drawImage(ship.getFileName(), ship.getWidth(), ship.getHeight(), 250, 7);
}
}
// 假设 drawImage 是已有的绘图方法
private void drawImage(String fileName, int width, int height, int x, int y) {
// 实际绘制逻辑
}
}</shipimage></shipimage>
⚠️ 若必须使用二维数组(不推荐,仅作技术说明):
需严格按“每列为一个战舰”理解数据,并转置逻辑——外层循环遍历列(战舰索引),内层按行取值:
public void createScene() {
if (ships == null || ships.length == 0 || ships[0].length == 0) return;
int shipCount = ships[0].length; // 列数 = 战舰数量
for (int col = 0; col <p>但此方式仍存在硬编码行号(ships[0][col])、无类型安全、异常风险高等缺陷。</p><p>? 总结: </p>
- 永远优先选择封装良好的 POJO + 集合,而非裸二维数组处理业务数据;
- 避免在循环中直接使用 ships[i][j] 而不明确维度语义;
- 使用 List
替代数组可获得编译期类型检查、增强 for 循环简洁性及扩展性; - 将字符串 "170" 立即解析为 int,而非延迟到每次调用 drawImage 时解析,提升性能与健壮性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











