This question already has answers here:
What is a NullPointerException, and how do I fix it?
                            
                                (12个答案)
                            
                    
                2年前关闭。
        

    

在BlueJ和Eclipse中,当检查String-equality时,我得到了nullpointer异常。

这是我的代码:

import java.util.Set;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Class Room - a room in an adventure game.
 *
 * This class is part of the "World of Zuul" application.
 * "World of Zuul" is a very simple, text based adventure game.
 *
 * A "Room" represents one location in the scenery of the game.  It is
 * connected to other rooms via exits.  For each existing exit, the room
 * stores a reference to the neighboring room.
 *
 * @author  Michael Kölling and David J. Barnes
 * @version 2016.02.29
 */

public class Room
{
    private String description;
    private String itemDescription;
    private HashMap<String, Room> exits;        // stores exits of this room.
    private ArrayList<Item> items;

    /**
     * Create a room described "description". Initially, it has
     * no exits. "description" is something like "a kitchen" or
     * "an open court yard".
     * @param description The room's description.
     */
    public Room(String description)
    {
        this.description = description;
        this.itemDescription = "This room contains: ";
        exits = new HashMap<>();
        items = new ArrayList<Item>();
    }

    public Room(String description, Item item)
    {
        items = new ArrayList<Item>();
        this.description = description;
        addItem(item);
        this.itemDescription = "This room contains: " + item.getLongDescription() ;
        exits = new HashMap<>();
    }
    /**
     * Define an exit from this room.
     * @param direction The direction of the exit.
     * @param neighbor  The room to which the exit leads.
     */
    public void setExit(String direction, Room neighbor)
    {
        exits.put(direction, neighbor);
    }

    public void addItem(Item item)
    {
        items.add(item);
        System.out.println(itemDescription.equals("This room contains: "));
        this.itemDescription = this.itemDescription + /*(this.itemDescription.equals("This room contains: ") ?
        "" : ", ")*/ ", " + item.getLongDescription();
    }

    public void removeItem(String shortItemDescription){
        int i= 0;
        Iterator<Item> it = items.iterator();
        while(it.hasNext()){
            if (it.next().getShortDescription().equals(shortItemDescription)){
                it.remove();
                i++;
            }
            else
                i++;
        }
    }

    public  ArrayList<Item> getItems(){
        return items;
    }

    /**
     * @return The short description of the room
     * (the one that was defined in the constructor).
     */
    public String getShortDescription()
    {
        return description;
    }

    /**
     * Return a description of the room in the form:
     *     You are in the kitchen.
     *     Exits: north west
     * @return A long description of this room
     */
    public String getLongDescription()
    {
        return "You are " + description + ".\n" + (itemDescription.equals("This room contains: ") ?
                "This room is empty" : itemDescription) + ".\n" + getExitString();
    }

    /**
     * Return a string describing the room's exits, for example
     * "Exits: north west".
     * @return Details of the room's exits.
     */
    private String getExitString()
    {
        String returnString = "Exits:";
        Set<String> keys = exits.keySet();
        for(String exit : keys) {
            returnString += " " + exit;
        }
        return returnString;
    }

    /**
     * Return the room that is reached if we go from this room in direction
     * "direction". If there is no room in that direction, return null.
     * @param direction The exit's direction.
     * @return The room in the given direction.
     */
    public Room getExit(String direction)
    {
        return exits.get(direction);
    }
}


在方法addItem(Item item)中,当检查字符串比较方法itemDescription.equals("This room contains: ")时以及在System.out.println()语句中以及在对itemDescription.equals("This room contains: ")的三元运算符测试中,都得到了nullpointer异常错误。

奇怪的是,getLongDescription()中的三元运算符可以正常工作。

最佳答案

如果使用Room构建Item实例。您在实例化addItem变量之前调用itemDescription

public Room(String description, Item item)
{
    // ...
    addItem(item);
    this.itemDescription = "This room contains: " + item.getLongDescription() ;
    // ...
}


因此,在方法addItem中,this.itemDescription仍然为空。

public void addItem(Item item)
{
    // ...
    System.out.println(itemDescription.equals("This room contains: "));
    // ...
}


这打破了。

若要更正此问题,请在实例化addItem后致电itemDescription。请注意,您不需要添加item描述,因为这已经在addItem方法中完成了。

public Room(String description, Item item)
{
    // ...
    this.itemDescription = "This room contains: ";
    addItem(item);
    // ...
}




您会后悔String itemDescription真的很快!

而是创建方法getRoomDescription,该方法将迭代items列表并生成该String itemDescription(使用StringBuilder)!

就像是

public String getRoomDescription(){
    StringBuilder sb = new StringBuilder("Rooms contains :");
    for(Item i : items){
         sb.append("\n".append(i.getLongDescription());
    }
    return sb.toString();
}


编辑itemDescription变量很麻烦,并且容易出现问题(就像您遇到的一样)。



最后一件事,您要做的测试

itemDescription.equals("This room contains: ")


应该给你相同的结果

items.size() == 0


但是更容易理解(items列表中没有值),并且如果您要编辑打印描述的方式,也不太容易出错。

07-24 20:53