You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题根源

核心问题是循环中重复自增变量,导致数组未完全初始化:

  1. 构造函数的外层for循环中,除了循环头的i++,循环末尾又手动添加i++,导致i每次增加2,原本要执行6次的循环实际只执行3次;
  2. 内层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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 15:34:51