Bukkit库存添加会产生nullpointerexception

时间:2015-03-19 00:07:36

标签: java minecraft bukkit

我的问题在于updateItem函数,我想通过setup函数将ItemStack添加到创建的库存'inv'中。但是这会抛出一个NullPointerException。

这是我的代码:

public class Shop {

    public static enum ShopMode { OPEN,CLOSED,FILLING }

    private int shopID;
    private Area area;
    private ShopMode mode;
    private boolean disabled;
    private ArrayList<ItemStack> items = new ArrayList<ItemStack>();
    private Inventory inv;
    private Connection conn = null;
    private PreparedStatement ps = null;
    private Statement st = null;
    private ResultSet rs = null;
    private String name;

    public Shop(int no) {
        shopID = no;
        updateItems();
        setup();
    }

    private void setup() {
        inv = Bukkit.createInventory(null, 36, "Shop "+name);
        updateItems();
    }
    private void updateItems() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost/odd","odd","odd");
            String sql = "SELECT * FROM `items` WHERE shopid = ?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, shopID);
            rs = ps.executeQuery();

            while (rs.next()) {
                String name = "";
                if (rs.getString("name") != "") {
                    name = rs.getString("name");
                    System.out.println("Name: "+name);
                }
                Material material = Material.valueOf(rs.getString("type"));
                int damage = rs.getInt("damage");
                System.out.println("Damage: "+damage);
                int count = rs.getInt("count");
                System.out.println("Count: "+count);
                //String[] ecs = null;
                if (rs.getString("enchantment") != "") {
                    //ecs = rs.getString("enchantment").split(";");
                }
                ItemStack is = new ItemStack(material,count,(byte) damage);
                //System.out.println(ecs.length);
                System.out.println("Enchants: "+rs.getString("enchantment"));
                /*if (ecs.length >= 1){
                    for (String enn : ecs) {
                        String[] enc = enn.split(enn);
                        is.addEnchantment(Enchantment.getByName(enc[0]),Integer.parseInt(enc[1]));
                    }
                }*/
                ItemMeta im = is.getItemMeta();
                if (rs.getString("lore") != "") {
                    List<String> list = new ArrayList<String>();
                    String[] t = rs.getString("lore").split(";");
                    for (int i = 0;i<t.length;i++) {
                        list.add(t[i]);
                    }
                    if (rs.getDouble("sell") <= 0) { 
                        list.add("Sorry, you can't sell this material to me."); 
                    } else { 
                        list.add("Sell: "+rs.getDouble("sell"));
                    }
                    if (rs.getDouble("buy") <= 0) { 
                        list.add("Sorry, you can't buy this item from me."); 
                    } else {
                        list.add("Buy: "+rs.getDouble("buy"));
                    }
                    im.setLore(list);
                    System.out.println("Lore: "+list.toString());
                }
                im.setDisplayName(name);
                System.out.println("DisplayName: "+name);
                is.setItemMeta(im);
                System.out.println("ItemStack: "+is.toString());
                inv.addItem(is);  // Line 176
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally { close(); }
    }    
}

这是我的错误日志:

[00:32:42 INFO]: Name: LOG
[00:32:42 INFO]: Damage: 2
[00:32:42 INFO]: Count: 1
[00:32:42 INFO]: Enchants:
[00:32:42 INFO]: Lore: [, Sorry, you can't sell this material to me., Sorry, you
 can't buy this item from me.]
[00:32:42 INFO]: DisplayName: LOG
[00:32:42 INFO]: ItemStack: ItemStack{LOG x 1, UNSPECIFIC_META:{meta-type=UNSPEC
IFIC, display-name=LOG, lore=[, Sorry, you can't sell this material to me., Sorr
y, you can't buy this item from me.]}}
[00:32:42 WARN]: java.lang.NullPointerException
[00:32:42 WARN]:        at no.jovang.odd.Shop.updateItems(Shop.java:176)
[00:32:42 WARN]:        at no.jovang.odd.Shop.<init>(Shop.java:39)
[00:32:42 WARN]:        at no.jovang.odd.manager.ShopManager.loadShops(ShopManag
er.java:106)
[00:32:42 WARN]:        at no.jovang.odd.manager.ShopManager.setup(ShopManager.j
ava:118)
[00:32:42 WARN]:        at no.jovang.odd.Odd$Startup.run(Odd.java:120)
[00:32:42 WARN]:        at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftTask.ru
n(CraftTask.java:71)
[00:32:42 WARN]:        at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftSchedul
er.mainThreadHeartbeat(CraftScheduler.java:350)
[00:32:42 WARN]:        at net.minecraft.server.v1_8_R1.MinecraftServer.z(Minecr
aftServer.java:709)
[00:32:42 WARN]:        at net.minecraft.server.v1_8_R1.DedicatedServer.z(Dedica
tedServer.java:316)
[00:32:42 WARN]:        at net.minecraft.server.v1_8_R1.MinecraftServer.y(Minecr
aftServer.java:634)
[00:32:42 WARN]:        at net.minecraft.server.v1_8_R1.MinecraftServer.run(Mine
craftServer.java:537)
[00:32:42 WARN]:        at java.lang.Thread.run(Unknown Source)
[00:32:42 INFO]: Name: LOG
[00:32:42 INFO]: Damage: 2
[00:32:42 INFO]: Count: 1
[00:32:42 INFO]: Enchants:
[00:32:42 INFO]: Lore: [, Sorry, you can't sell this material to me., Sorry, you
 can't buy this item from me.]
[00:32:42 INFO]: DisplayName: LOG
[00:32:42 INFO]: ItemStack: ItemStack{LOG x 1, UNSPECIFIC_META:{meta-type=UNSPEC
IFIC, display-name=LOG, lore=[, Sorry, you can't sell this material to me., Sorr
y, you can't buy this item from me.]}}

2 个答案:

答案 0 :(得分:0)

在Shop

的构造函数中
public Shop(int no) {
   shopID = no;
   updateItems();
   setup();
}

你应该删除对updateItems()的调用。这是因为首先需要调用setup()方法才能初始化 inv 成员变量。此外,由于setup()调用updateItems()本身,因此无需在构造函数中调用updateItems()。

如果您进行此更改,那么当您的代码到达此行时

inv.addItem(is);    

inv不会为null,这就是您所看到的异常的原因。

答案 1 :(得分:0)

当您尝试在值为null的对象上调用方法时,抛出NullPointerException。错误日志表明错误位于 176 行,即此行:

inv.addItem(is);

inv被抛出,因为null等于inv.addItem(is)

当您的代码到达inv时,null没有值(它是.addItem(is)),因此,编译器不知道要调用inv的内容,导致你的插件抛出NullPointerException

您在setup()函数中初始化public Shop(int no){ shopID = no; //this works fine updateItems(); //this causes the NPE - inv is not yet initialized setup(); //inv is initialized here, so it is now safe to call updateItems() } ,因此,而不是使用:

updateItems()

您应该切换位置setup()public Shop(int no){ shopID = no; //this works fine setup(); //inv is initialized here, so it is now safe to call updateItems() updateItems(); //it is safe to call this because 'inv' was just initialized } ,然后使用:

setup()

在初始化updateItems() 后,您的inv方法看起来似乎public Shop(int no){ shopID = no; setup(); } ,因此您可以将NullPointerException缩短为:

public class Shop {

    public static enum ShopMode { OPEN, CLOSED, FILLING }

    //...

    public Shop(int no){
        shopID = no;
        setup();
    }

    private void setup(){
        inv = Bukkit.createInventory(null, 36, "Shop "+name);
        updateItems();
    }

    private void updateItems(){
        //...
    }
}

最后,这就是您的代码应该是这样的:

{{1}}