即使变量不为null,也会出现NullPointerException

时间:2014-12-30 20:01:40

标签: java object nullpointerexception queue

我目前正在设计一个模拟机场的程序。我遇到了一个问题,我已经尽力找出问题,发布到这个网站是我最后的选择。

它一直给我一个“线程中的异常”主“在AirportApp.main(AirportApp.java:119)的java.lang.NullPointerException”,它位于// Landings部分下面,代码为

System.out.println(plane1.getCapacity());

我打印的原因是为了确保plane1.getCapacity不是null。这是因为当我尝试下面的代码时

if(plane1.getCapacity() < 300);

它给了我NullPointerException错误。我做了打印,但没有返回null。

我在这里要做的是每当飞机降落时,它将被分配到一个空门。如果飞机的容量为300或更多,它将仅分配到第4或第5门。其他平面可以分配到任何门。

我注意到只有在容量超过300时才会发生错误。

我已经一遍又一遍地查看我的代码,确保所有变量都已初始化,但我仍然找不到任何错误。任何帮助或提示将不胜感激。为凌乱的代码道歉。

主要课程。

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class AirportApp {


public static void main(String[] args) 
{
    Scanner sc = new Scanner(System.in);
    Random rn = new Random();

    String [] flightNames = {"SQ", "MI", "TZ", "TR", "EK", "MO", "FC"};
    int [] flightNum = {8421, 5361, 6342, 6135, 8424, 7424, 5435};

    Queue landingRunway = new Queue(10);
    Queue takeoffRunway = new Queue(10);
    Queue planesQueue = new Queue(100);
    Queue gatesQueue = new Queue(100);
    ArrayList<Gate> allGates = new ArrayList();

    for(int i = 1 ; i < 6 ; i++)
    {
        allGates.add(new Gate(i, 0, 0, true));
    }

    int minutes = 0;
    int planesMissedTime = 0;
    Boolean highWinds = null;
    int tookOffPlanes = 0;
    int smallCapPlanes = 0;
    int largeCapPlanes = 0;
    int landedPlanes = 0;

    System.out.println("Please key in the number of minutes you want " 
                        + "the program to run: ");
    int desiredMinutes = sc.nextInt();

    while(minutes < desiredMinutes)
    {
        //Randomise wind warnings
        int windRandom = rn.nextInt(2) + 1;
        if(windRandom == 1)
        {
            highWinds = true;
        }
        if(windRandom == 2)
        {
            highWinds = false;
        }

        //Empty the gates

        for(Gate c : allGates)
        {
            if(c.getAvailability() == false)
            {
                c.addMinInQueue(1);
                if(c.getMinInQueue() == 15)
                {
                    c.isAvailable();
                }
            }
        }

        //Every 2 minutes

        if(minutes % 2 == 0)
        {
            //Randomise flight names and number

            int index = rn.nextInt(flightNames.length);
            int index1 = rn.nextInt(flightNum.length);
            String name = flightNames[index];
            int num = flightNum[index1];

            //Randomise plane assignment

            int planeDirection = rn.nextInt(2) + 1;
            int planeCap = rn.nextInt(401) + 100;

            //Arrival Planes

            if(planeDirection == 1)
            {
                planesQueue.enqueue(new Plane(num, name, planeCap, 5 , 0 ));
                System.out.println("A plane has been generated.");
            }

            //Departure Planes

            if(planeDirection == 2)
            {
                planesQueue.enqueue(new Plane(num, name, planeCap, 0 , 5 ));
                System.out.println("A plane has been generated.");
            }

            //Take-Offs

            if(!takeoffRunway.isEmpty())
            {
                System.out.println("A plane has departed.");
                Plane departPlane = (Plane) takeoffRunway.dequeue();
                if (departPlane.getCapacity() < 300)
                {
                    smallCapPlanes++;
                }
                tookOffPlanes++;
            }
        }

        //Landings

        if(minutes % 3 == 0 && !landingRunway.isEmpty())
        {
            System.out.println("A plane has landed.");
            gatesQueue.enqueue(landingRunway.dequeue());
            landedPlanes++;
            loop1:
            for(Gate e : allGates)
            {
                if(e.getAvailability() == true)
                {
                    Plane plane1 = (Plane) gatesQueue.dequeue();
                    System.out.println(plane1.getCapacity());
                    if(plane1.getCapacity() < 300)
                    {
                        e.addNumOfPlanes(1);
                        e.setAvailability(false);
                        break loop1;
                    }
                    if(plane1.getCapacity() > 300)
                    {
                         largeCapPlanes++;
                        if(e.getGateId() == 4 || e.getGateId() == 5)
                        {
                            e.addNumOfPlanes(1);
                            e.setAvailability(false);
                            break loop1;
                        }
                    }
                }
            }
        }

        //Plane assigned to takeoff or landing queue

        if(minutes % 5 == 0)
        {
            Plane item = (Plane) planesQueue.peek();
            if(item.getArrivalTime() == 5 && landingRunway.isEmpty()
                    && highWinds == false)
            {
                landingRunway.enqueue(planesQueue.dequeue());
                System.out.println("A plane has been assigned to " 
                                    + "the landing queue.");
            }
            else if(item.getDepartureTime() == 5 &&
                    takeoffRunway.isEmpty() && highWinds == false)
            {
                takeoffRunway.enqueue(planesQueue.dequeue());
                System.out.println("A plane has been assigned to " 
                                    + "the takeoff queue.");
            }
            else
            {
                planesMissedTime++;
            }
        }
        minutes++;
    }

第1类

public class Plane 
{
private int flightNo;
private String flightName;
private int capacity;
private int timeOfArrival;
private int timeOfDeparture;
private int delayTime;

public Plane(int flightNo, String flightName, int capacity, 
                int timeOfArrival, int timeOfDeparture)
{
    this.flightNo = flightNo;
    this.flightName = flightName;
    this.capacity = capacity;
    this.timeOfArrival = timeOfArrival;
    this.timeOfDeparture = timeOfDeparture;
}


public void setFlightNum(int flightNo)
{
    this.flightNo = flightNo;
}

public int getFlightNum()
{
    return this.flightNo;
}

public void setFlightName(String flightName)
{
    this.flightName = flightName;
}

public String getflightName()
{
    return this.flightName;
}

public void addCapacity(int capacity)
{
    this.capacity = capacity;
}

public int getCapacity()
{
    return this.capacity;
}

public void setArrivalTime(int newArrivalTime)
{
    this.timeOfArrival = newArrivalTime;
}

public int getArrivalTime()
{
    return this.timeOfArrival;
}

public void setDepartureTime(int newDepartureTime)
{
    this.timeOfDeparture = newDepartureTime;
}

public int getDepartureTime()
{
    return this.timeOfDeparture;
}
}

第2类

public class Gate 
{
private int gateID;
private int numOfPlanes;
private int minInQueue;
private boolean availability;

public Gate(int id, int numPlanes, int minQueue, boolean available)
{
    this.gateID = id;
    this.numOfPlanes = numPlanes;
    this.minInQueue = minQueue;
    this.availability = available;
}

public int getGateId()
{
    return this.gateID;
}

public void setGateId(int newID)
{
    this.gateID = newID;
}

public int getNumOfPlanes()
{
    return this.numOfPlanes;
}

public void addNumOfPlanes(int addNum)
{
    this.numOfPlanes += addNum;
}

public int getMinInQueue()
{
    return this.minInQueue;
}

public void setMinInQueue(int setMin)
{
    this.minInQueue = 0;
}

public void addMinInQueue(int addMin)
{
    this.minInQueue += addMin;
}

public boolean getAvailability()
{
    return this.availability;
}

public void setAvailability(Boolean setAvailability)
{
    this.availability = setAvailability; 
}

public void isAvailable()
{
    this.availability = true;
    this.minInQueue = 0;
}
}

队列类

class Queue
{
    private int count;
    private int front = 0;      
    private int rear = 0;       
    private Object [] items;    

    public Queue(int maxSize)
    {
            count = 0;
            front = -1;
            rear = -1;
            items = new Object [maxSize];
    }

    public boolean enqueue (Object x)
    {
        if (count == items.length)
        {
            return false;
        }
        else
        {
            rear = (rear + 1) % items.length;
            items[rear] = x;
            if (count == 0) 
            {               
                front = 0;
            }
            count++;
            return true;
        }
    }

    public Object dequeue()
    {
        if (count == 0) 
        {
            return null;
        }
        else 
        {
            Object result = items[front]; 
            front = (front + 1) % items.length; 
            count--;
            if (count == 0) 
            {               
                front = -1;
                rear = -1;
            }

            return result;
        }           
    }

    public int size()
    {
        return count;
    }

    public boolean isEmpty()
    {
        if (count == 0)
            {
            return true;
            }
        else
            {
            return false;
            }
    }

    public Object peek()
    {
        if (count == 0) 
        {
            return null;
        }
        else
        {
            return items[front];
        }
    }

}

2 个答案:

答案 0 :(得分:2)

问题在于第二个if语句

  

if (plane1.getCapacity() > 300) { largeCapPlanes++; if (e.getGateId() == 4 || e.getGateId() == 5) { e.addNumOfPlanes(1); e.setAvailability(false); break loop1; } }

如果门是4或5,你只能打破你的循环。所以,如果它不是4号门或5号门,那么你的代码将循环回到下一个门,从队列中抓取另一个平面(这是空的,您的plane1现在是null),然后尝试获取容量。在那里你得到你的空指针。

注意:小心嵌套循环和if语句。这是虫子享受生活的地方。

快乐的编码!

答案 1 :(得分:0)

我运行代码并且在我尝试了大量的时间(1000)之前没有得到错误。我假设错误与Plane plane1 = (Plane) gatesQueue.dequeue();部分有关。我会在那里抛出一些调试语句,看看对于大n是否正确生成了Queue。如果dequeue()返回null,则plane1也会null

编辑:

所以我调试了它并确认问题出在该循环中的plane对象上。你排列了你的大门:gatesQueue.enqueue(landingRunway.dequeue());然后你运行一个循环:for(Gate e : allGates)然后你出列队列:Plane plane1 = (Plane) gatesQueue.dequeue();

如果您的队列数量超过您的队列数量,则会返回null。因此,您要么必须更改队列的执行方式,要么检查for循环以检查队列的大小。

当你执行System.out.println()时看到一个数字的原因是因为它正在显示,返回到循环的顶部,然后在运行之前再次尝试获取plane对象打印再次。