显示java.lang.NullPointerException

时间:2011-09-19 11:52:24

标签: java nullpointerexception

public class CustomerAgent extends Agent {
    private String name;
    private int hungerLevel = 5;  // Determines length of meal
    private RestaurantGui gui;
    private double money = 25;
    private double bill = 0;

    // ** Agent connections **
    private HostAgent host;
    private WaiterAgent waiter;
    private CashierAgent cashier;
    Restaurant restaurant;
    private Menu menu;
    Timer timer = new Timer();
    GuiCustomer guiCustomer; //for gui
   // ** Agent state **
    private boolean isHungry = false; //hack for gui
    public enum AgentState
        {DoingNothing, WaitingInRestaurant, SeatedWithMenu, WaiterCalled, WaitingForFood, Eating, WaitingForBill, Paying};
    //{NO_ACTION,NEED_SEATED,NEED_DECIDE,NEED_ORDER,NEED_EAT,NEED_LEAVE};
        private AgentState state = AgentState.DoingNothing;//The start state
    public enum AgentEvent 
        {gotHungry, beingSeated, decidedChoice, waiterToTakeOrder, foodDelivered, doneEating, BillDelivered,DonePaying };
    private AgentEvent event;//Messages set the event

    /** Constructor for CustomerAgent class 
     * @param name name of the customer
     * @param gui reference to the gui so the customer can send it messages
     */
    public CustomerAgent(String name, RestaurantGui gui, Restaurant restaurant) {
    super();
    this.gui = gui;
    this.name = name;
    this.restaurant = restaurant;
    //this.cashier = cashier;
    guiCustomer = new GuiCustomer(name.substring(0,2), new Color(0,255,0), restaurant);
    }
    public CustomerAgent(String name, Restaurant restaurant) {
    super();
    this.gui = null;
    this.name = name;
    this.restaurant = restaurant;
    guiCustomer = new GuiCustomer(name.substring(0,1), new Color(0,255,0), restaurant);
    }
    // *** MESSAGES ***
    /** Sent from GUI to set the customer as hungry */
    public void setHungry() {
    event = AgentEvent.gotHungry;
    isHungry = true;
    print("I'm hungry");
    pickAndExecuteAnAction();//stateChanged();
    }
    /** Waiter sends this message so the customer knows to sit down 
     * @param waiter the waiter that sent the message
     * @param menu a reference to a menu */
    public void msgFollowMeToTable(WaiterAgent waiter, Menu menu) {
    this.menu = menu;
    this.waiter = waiter;
    print("Received msgFollowMeToTable from" + waiter);
    //state = AgentState.NEED_DECIDE;
    event = AgentEvent.beingSeated;
    pickAndExecuteAnAction();//stateChanged();
    }
    /** Waiter sends this message to take the customer's order */
    public void msgDecided(){
    event = AgentEvent.decidedChoice;
    pickAndExecuteAnAction();//stateChanged(); 
    }
    /** Waiter sends this message to take the customer's order */
    public void msgWhatWouldYouLike(){
    event = AgentEvent.waiterToTakeOrder;
    pickAndExecuteAnAction();//stateChanged(); 
    }

    /** Waiter sends this when the food is ready 
     * @param choice the food that is done cooking for the customer to eat */
    public void msgHereIsYourFood(String choice) {
    event = AgentEvent.foodDelivered;
    pickAndExecuteAnAction();  //stateChanged();
    }
    /** Timer sends this when the customer has finished eating */
    public void msgDoneEating() {
    event = AgentEvent.doneEating;
    pickAndExecuteAnAction(); //stateChanged(); 
    }

    /** Waiter sends this when the Bill is ready
     */
    public void msgHereIsYourBill(WaiterAgent waiter, double price){
        this.waiter = waiter;
        event = AgentEvent.BillDelivered;
        bill = price;
        print("Price for the food is"+ bill);
        pickAndExecuteAnAction();
    }


    /** Scheduler.  Determine what action is called for, and do it. */
    protected boolean pickAndExecuteAnAction() {

    //Simple finite state machine
    if (state == AgentState.DoingNothing){
        if (event == AgentEvent.gotHungry)  {
        goingToRestaurant();
        state = AgentState.WaitingInRestaurant;
        return true;
        }
        // elseif (event == xxx) {}
    }
    if (state == AgentState.WaitingInRestaurant) {
        if (event == AgentEvent.beingSeated)    {
        makeMenuChoice();
        state = AgentState.SeatedWithMenu;
        return true;
        }
    }
    if (state == AgentState.SeatedWithMenu) {
        if (event == AgentEvent.decidedChoice)  {
        callWaiter();
        state = AgentState.WaiterCalled;
        return true;
        }
    }
    if (state == AgentState.WaiterCalled) {
        if (event == AgentEvent.waiterToTakeOrder)  {
        orderFood();
        state = AgentState.WaitingForFood;
        return true;
        }
    }
    if (state == AgentState.WaitingForFood) {
        if (event == AgentEvent.foodDelivered)  {
        eatFood();
        state = AgentState.Eating;
        return true;
        }
    }
    if (state == AgentState.Eating) {
        if (event == AgentEvent.doneEating) {
        askForBill();
        state = AgentState.WaitingForBill;
        return true;
        }
    }

    if(state == AgentState.WaitingForBill)
    {
        if (event == AgentEvent.BillDelivered)
        {

            payBill();
            print("Got here!");
            state = AgentState.Paying;
            return true;
        }
    }

    if (state == AgentState.Paying)
    {
        if (event == AgentEvent.DonePaying)
        {
            leaveRestaurant();
            state = AgentState.DoingNothing;
            return true;
        }
    }

    print("No scheduler rule fired, should not happen in FSM, event="+event+" state="+state);
    return false;
    }



    // *** ACTIONS ***

    /** Goes to the restaurant when the customer becomes hungry */
    private void goingToRestaurant() {
    print("Going to restaurant");
    guiCustomer.appearInWaitingQueue();
    host.msgIWantToEat(this);//send him our instance, so he can respond to us
    stateChanged();
    }

    /** Starts a timer to simulate the customer thinking about the menu */
    private void makeMenuChoice(){
    print("Deciding menu choice...(3000 milliseconds)");
    timer.schedule(new TimerTask() {
        public void run() {  
        msgDecided();       
        }},
        3000);//how long to wait before running task
    stateChanged();
    }
    private void callWaiter(){
    print("I decided!");
    waiter.msgImReadyToOrder(this);
    stateChanged();
    }

    /** Picks a random choice from the menu and sends it to the waiter */
    private void orderFood(){
    String choice = menu.choices[(int)(Math.random()*4)];
    print("Ordering the " + choice);
    waiter.msgHereIsMyChoice(this, choice);
    stateChanged();
    }

    /** Starts a timer to simulate eating */
    private void eatFood() {
    print("Eating for " + hungerLevel*1000 + " milliseconds.");
    timer.schedule(new TimerTask() {
        public void run() {
        msgDoneEating();    
        }},
        getHungerLevel() * 1000);//how long to wait before running task
    stateChanged();
    }


    /** When the customer is done eating, he leaves the restaurant */
    private void leaveRestaurant() {
    print("Leaving the restaurant");
    guiCustomer.leave(); //for the animation
    waiter.msgDoneEatingAndLeaving(this);
    isHungry = false;
    stateChanged();
    gui.setCustomerEnabled(this); //Message to gui to enable hunger button

    //hack to keep customer getting hungry. Only for non-gui customers
    if (gui==null) becomeHungryInAWhile();//set a timer to make us hungry.
    }

    /** This starts a timer so the customer will become hungry again.
     * This is a hack that is used when the GUI is not being used */
    private void becomeHungryInAWhile() {
    timer.schedule(new TimerTask() {
        public void run() {  
        setHungry();            
        }},
        15000);//how long to wait before running task
    }

    private void askForBill()
    {
        waiter.msgNeedBill(this);
        print("Asking for BIll");
        stateChanged();
    }
    private void payBill()
    {
        print("Do you Exist");
        cashier.msgHereIsMyPayment(this);
        stateChanged();
    }
}

我的payBill方法会在遇到cashier.msgHereIsMyPayment时抓住意外异常。我不知道为什么会发生这种情况

3 个答案:

答案 0 :(得分:3)

cashier永远不会设置为任何值,因此它将为null

null引用上调用任何方法会产生NullPointerException

要么需要在构造函数中接受Cashier对象,并设置字段自己创建一个。

答案 1 :(得分:1)

Cashier是一个私有成员变量,但我没有在你的构造函数中看到它。如果没有初始化,则它为空。

答案 2 :(得分:0)

收银员为空。我没有看到它被分配到任何地方。除非另行初始化,否则所有类字段(非基元)都设置为空。