如何在Scanner输入中使用其他类变量?船坞数组打印为null问题
解决Scanner异常与数组打印null的问题
老哥,我来帮你捋捋这个问题——你遇到的Scanner异常和数组输出null,大概率是踩了两个Java新手常犯的坑:数组内的Ship对象未提前实例化,或是Scanner输入逻辑没处理好(比如换行符残留、非法输入导致异常)。下面给你一步步拆解解决方案:
1. 先确保Ship类的定义正确
首先得有一个能存船舶名称和尺寸的实体类,建议带构造方法方便直接初始化:
class Ship { String shipName; int shipSize; // 构造方法:直接传入名称和尺寸初始化对象 public Ship(String shipName, int shipSize) { this.shipName = shipName; this.shipSize = shipSize; } }
2. 正确初始化数组+处理Scanner输入
很多人会犯的错是:只声明了Ship[] ships = new Ship[10];,但没给数组里的每个位置创建Ship对象,导致元素全是null。另外,Scanner输入时要处理非法输入(比如用户输入非数字尺寸),还要清理换行符残留。
给你一个完整的可运行示例:
import java.util.Scanner; public class ShipDockingSystem { public static void main(String[] args) { // 初始化能存10艘船的数组 Ship[] dockedShips = new Ship[10]; Scanner inputScanner = new Scanner(System.in); for (int i = 0; i < dockedShips.length; i++) { // 读取船舶名称 System.out.println("请输入第" + (i+1) + "艘船的名称:"); String shipName = inputScanner.nextLine(); // 读取船舶尺寸,加异常处理避免崩溃 int shipSize = 0; boolean isInputValid = false; while (!isInputValid) { System.out.println("请输入第" + (i+1) + "艘船的尺寸:"); if (inputScanner.hasNextInt()) { shipSize = inputScanner.nextInt(); isInputValid = true; } else { System.out.println("无效输入!请输入数字类型的尺寸。"); inputScanner.next(); // 吃掉无效输入,防止死循环 } } inputScanner.nextLine(); // 清理nextInt()后的换行符,避免下一次nextLine()读空字符串 // 关键!给数组的当前位置实例化Ship对象,不然会是null dockedShips[i] = new Ship(shipName, shipSize); } inputScanner.close(); // 调用打印方法 printDockingSlots(dockedShips); } // 打印船舶停靠位的方法 public static void printDockingSlots(Ship[] ships) { System.out.println("\n=== 船舶停靠位列表 ==="); for (int i = 0; i < ships.length; i++) { // 判空避免NullPointerException if (ships[i] != null) { System.out.printf("停靠位%d:船舶名称「%s」,尺寸:%d%n", i+1, ships[i].shipName, ships[i].shipSize); } else { System.out.printf("停靠位%d:未分配船舶%n", i+1); } } } }
3. 常见问题排查
- 为什么数组打印出null?
核心原因是你只创建了数组容器,却没给数组内的每个元素创建Ship对象。比如只写了Ship[] ships = new Ship[10];,但没有ships[i] = new Ship(...),数组元素默认值就是null。 - 为什么Scanner会抛出异常?
最常见的场景是:用户输入尺寸时输入了非数字内容,触发InputMismatchException;或者在nextInt()后没有调用nextLine()清理换行符,导致下一次nextLine()读取到空字符串,看起来像“输入被跳过”。上面的代码已经通过循环处理非法输入、清理换行符解决了这些问题。 - 如果用Setter方法而不是构造方法?
那要记得先实例化对象:ships[i] = new Ship();,再调用ships[i].setShipName(name);和ships[i].setShipSize(size);,同样不能跳过对象实例化的步骤。
内容的提问来源于stack exchange,提问作者S.smith94
相关产品推荐
相关产品推荐

