Minecraft Spigot/Bukkit插件在相等性检查时抛出NullPointerException



我正在尝试创建一个菜单,我想确保所有玩家在加入时都有指南针。

我的代码不起作用 - 如果您的库存中有一个无名指南针,它只是不会为您提供指南针。如果我不检查这些== null,我的代码给出了具有上述条件的NullPointerException

Eclipse 不显示任何错误。我做错了什么?

package me.psrcek.compassMenu.listeners;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class PlayerJoinListener implements Listener {
    @EventHandler
    public void onJoin(PlayerJoinEvent e) {
        ItemStack[] inv = e.getPlayer().getInventory().getContents();
        
        for (ItemStack item : inv) {
            if (item == null) continue;
            
            if (item.getType().equals(Material.COMPASS)) {
                if (item.getItemMeta().getDisplayName() == null) continue;
                
                if (item.getItemMeta().getDisplayName().equals(ChatColor.RESET + "" + ChatColor.AQUA + "Menu")) {
                    e.getPlayer().sendMessage("found proppertly named compass");
                    return;
                }
            }
        }
        
        ItemStack compass = new ItemStack(Material.COMPASS);
        ItemMeta compassMeta = compass.getItemMeta();
        
        compassMeta.setDisplayName(ChatColor.RESET + "" + ChatColor.AQUA + "Menu");
        
        compass.setItemMeta(compassMeta);
        
        e.getPlayer().getInventory().addItem(compass);
        e.getPlayer().updateInventory();
    }
}
我不知道

为什么这有效,但正在改变

item.getType().equals(Material.COMPASS)

item.getType() == Material.COMPASS

让它工作。我一直认为这些是一回事。

我看到几个地方可能会出现NullPointerException。首先,您正在检查该项目是否为空,如果是,则检查它是否为指南针。但如果它是空的,它也不能是指南针。试试这个:

if(item != null){
    if(item.getType() == Material.COMPASS){
    }
}

我马上看到的第二个地方是同一个 for 循环,当你得到指南针的物品元时。好吧,Bukkit不喜欢说itemStack有一个itemMeta,直到你给它分配一个,所以试试这个:

if(item.getType() == Material.COMPASS){
    if(item.hasItemMeta()){
        if(item.getItemMeta().getDisplayName().contains(ChatColor.AQUA + "Menu"){
            p.sendMessage("found properly named compass");
            return;
        }
    }
}

如果你想要一种更简单的方法来解决这个问题,我建议使用以下示例代码:

ItemStack compass = new ItemStack(Material.COMPASS);
ItemMeta compassMeta = compass.getItemMeta();
//No need to use ChatColor.RESET before the text has a color
compassMeta.setDisplayName(ChatColor.AQUA + "Menu");
compass.setItemMeta(compassMeta);
for(ItemStack item:e.getPlayer().getInventory().getContents()){
    if(item != null){
        if(item.equals(compass)){
            p.sendMessage("found properly named compass");
            return;
        }
    }
}

希望这对您有帮助。

.equals 方法和==运算符不是一回事。

.equals比较对象的值。

==比较对象的引用(内存中的位置)。

例:

Integer x = 10;
Integer y = 10;
// is false
System.out.println(x == y)
// is true
System.out.println(x.equals(y)) 

相关内容