Java停车场项目出现NullPointerException:pl.parkingLot[5]为null
Java停车场项目NullPointerException问题解决
问题描述
运行程序时抛出空指针异常:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "ParkingSpace.getSpaceNum()" because "pl.parkingLot[5]" is null at ParkingLot.main(ParkingLot.java:67)
原本计划通过构造函数的for循环初始化parkingLot数组,确保每个索引都对应ParkingSpace对象,但pl.parkingLot[5]却为null;预期控制台输出5和4,实际抛出异常。
代码片段
ParkingLot类
public class ParkingLot { ParkingSpace[] parkingLot; int numSpaces; int numFloors; ParkingLot(int numSpaces, int numFloors){ this.numSpaces = numSpaces; this.numFloors = numFloors; ParkingSpace[] array = new ParkingSpace[numSpaces]; parkingLot = new ParkingSpace[numSpaces]; char currentFloor = 'A'; for(int i = 0; i < numFloors; i++){ for(int j = 0; j < numSpaces; j++){ parkingLot[j] = new ParkingSpace(j, currentFloor, false); if(j<4){ parkingLot[j].isCompact = true; } j++; } currentFloor++; i++; } } ParkingSpace enterLot(boolean com){ ParkingSpace returnValue = new ParkingSpace(0,'A', false); for(int i = 0; i < numFloors; i++) { for (int j = 0; j < numSpaces; j++) { if (!parkingLot[j].isOccupied) { if (com) { returnValue = parkingLot[j]; } else if (i > 3) { returnValue = parkingLot[j]; } else { j++; } } else { j++; } } i++; } return returnValue; } void leaveLot(ParkingSpace space){ for(int i = 0; i < numFloors; i++){ if(i == space.floor){ for(int j = 0; j < numSpaces; j++){ if(j == space.spaceNum){ space.isOccupied = false; }else{ j++; } } }else{ i++; } } } public static void main(String[] args){ ParkingLot pl = new ParkingLot(6, 6); System.out.println(pl.parkingLot[5].getSpaceNum()); System.out.println(pl.enterLot(false)); } }
ParkingSpace类
public class ParkingSpace { int spaceNum; char floor; boolean isCompact; boolean isOccupied; ParkingSpace(int spaceNum, char floor, boolean isCompact){ this.spaceNum = spaceNum; this.floor = floor; this.isCompact = isCompact; isOccupied = false; } int getSpaceNum(){ return spaceNum; } char getFloor(){ return floor; } boolean getCompact(){ return isCompact; } boolean getOccupied(){ return isOccupied; } void setOccupied(boolean value){ isOccupied = value; } String toAString(){ char compact; char occupied; if(isCompact){ compact = 'C'; }else{ compact = 'N'; } if(isOccupied){ occupied = 'X'; }else{ occupied = 'O'; } return(floor + spaceNum + " (" + compact + " " + occupied + ")"); } }
问题根源
核心问题是循环中重复自增变量,导致数组未完全初始化:
- 构造函数的外层
for循环中,除了循环头的i++,循环末尾又手动添加i++,导致i每次增加2,原本要执行6次的循环实际只执行3次; - 内层
for循环同理,循环头的j++加上循环末尾的j++,让j每次增加2,numSpaces=6时,只会初始化索引0、2、4的位置,索引1、3、5始终为null,这就是pl.parkingLot[5]抛出空指针的原因。
另外,enterLot和leaveLot方法中也存在同样的重复自增问题,会导致逻辑遍历不完整;原代码中parkingLot数组长度仅设为numSpaces,未考虑楼层数,会出现不同楼层车位覆盖的问题。
修复方案
1. 修复构造函数的循环与数组长度
去掉循环中手动添加的自增操作,同时修正数组长度为总车位数(每层车位×楼层数):
ParkingLot(int numSpaces, int numFloors){ this.numSpaces = numSpaces; this.numFloors = numFloors; parkingLot = new ParkingSpace[numSpaces * numFloors]; char currentFloor = 'A'; for(int i = 0; i < numFloors; i++){ for(int j = 0; j < numSpaces; j++){ int index = i * numSpaces + j; parkingLot[index] = new ParkingSpace(j, currentFloor, j < 4); } currentFloor++; } }
2. 修复enterLot方法的循环逻辑
去掉重复自增,优化条件判断并直接返回找到的车位:
ParkingSpace enterLot(boolean com){ for(int i = 0; i < numFloors; i++) { for (int j = 0; j < numSpaces; j++) { int index = i * numSpaces + j; ParkingSpace space = parkingLot[index]; if (!space.isOccupied) { if (com || i > 3) { return space; } } } } return null; }
3. 修复leaveLot方法的逻辑
直接修改传入的车位对象,或通过索引查找后修改:
void leaveLot(ParkingSpace space){ space.setOccupied(false); // 如需校验车位归属,可使用以下逻辑: // for(int i = 0; i < numFloors; i++){ // for(int j = 0; j < numSpaces; j++){ // int index = i * numSpaces + j; // ParkingSpace s = parkingLot[index]; // if(s.floor == space.floor && s.spaceNum == space.spaceNum){ // s.setOccupied(false); // return; // } // } // } }
4. 修复ParkingSpace的toString方法
修改方法名符合Java规范,确保打印对象时自动调用:
@Override public String toString(){ char compact = isCompact ? 'C' : 'N'; char occupied = isOccupied ? 'X' : 'O'; return floor + String.valueOf(spaceNum) + " (" + compact + " " + occupied + ")"; }
5. 调整main方法
适配数组长度修改后的索引访问:
public static void main(String[] args){ ParkingLot pl = new ParkingLot(6, 6); System.out.println(pl.parkingLot[5].getSpaceNum()); ParkingSpace space = pl.enterLot(false); System.out.println(space != null ? space : "No available space"); }
内容的提问来源于stack exchange,提问作者h_s_06
相关产品推荐
相关产品推荐

