首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法修复NPE

无法修复NPE
EN

Stack Overflow用户
提问于 2013-06-23 19:18:12
回答 1查看 245关注 0票数 4

错误:

代码语言:javascript
复制
Caused by: java.lang.NullPointerException
    at com.mcvigor.RunePlayer.getSkillLevel(RunePlayer.java:90)
    at com.mcvigor.utils.SkillUtils.getChances(SkillUtils.java:12)
    at com.mcvigor.listeners.MiningListener.breakBlocks(MiningListener.java:118)

我正在尝试调用SkillUtils.getChances,结果出现了NPE。我试图通过检查我的代码来查找错误,但我似乎找不到为什么会出现这个错误。

RunePlayer.java:

代码语言:javascript
复制
package com.mcvigor;

import java.util.HashMap;

public class RunePlayer {

    private HashMap<Skills, Integer> skills = new HashMap<Skills, Integer>();
    private HashMap<Skills, Integer> skillXP = new HashMap<Skills, Integer>();
    private String name;

    public RunePlayer(String name) {
        new RunePlayer(name, 1, 1, 3, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    }


    public RunePlayer(String name, int agility, int attack, int combat, int constitution, 
            int construction, int cooking, int crafting, int defence, int dungeoneering,
            int farming, int firemaking, int fishing, int fletching, int herblore, int hunter, int magic, int mining,
            int prayer, int ranged, int runecrafting, int slayer, int smithing, int strength,
            int summoning, int thieving, int woodcutting, int agilityXP, int attackXP, int combatXP, int constitutionXP, 
            int constructionXP, int cookingXP, int craftingXP, int defenceXP, int dungeoneeringXP,
            int farmingXP, int firemakingXP, int fishingXP, int fletchingXP, int herbloreXP, int hunterXP, int magicXP, int miningXP,
            int prayerXP, int rangedXP, int runecraftingXP, int slayerXP, int smithingXP, int strengthXP,
            int summoningXP, int thievingXP, int woodcuttingXP) {
        setName(name);
        skills.put(Skills.AGILITY, agility);
        skills.put(Skills.ATTACK, attack);
        skills.put(Skills.COMBAT, combat);
        skills.put(Skills.CONSTITUTION, constitution);
        skills.put(Skills.CONSTRUCTION, construction);
        skills.put(Skills.COOKING, cooking);
        skills.put(Skills.CRAFTING, crafting);
        skills.put(Skills.DEFENCE, defence);
        skills.put(Skills.DUNGEONEERING, dungeoneering);
        skills.put(Skills.FARMING, farming);
        skills.put(Skills.FIREMAKING, firemaking);
        skills.put(Skills.FISHING, fishing);
        skills.put(Skills.FLETCHING, fletching);
        skills.put(Skills.HERBLORE, herblore);
        skills.put(Skills.HUNTER, hunter);
        skills.put(Skills.MAGIC, magic);
        skills.put(Skills.MINING, mining);
        skills.put(Skills.PRAYER, prayer);
        skills.put(Skills.RANGED, ranged);
        skills.put(Skills.RUNECRAFTING, runecrafting);
        skills.put(Skills.SLAYER, slayer);
        skills.put(Skills.SMITHING, smithing);
        skills.put(Skills.STRENGTH, strength);
        skills.put(Skills.SUMMONING, summoning);
        skills.put(Skills.THIEVING, thieving);
        skills.put(Skills.WOODCUTTING, woodcutting);
        skillXP.put(Skills.AGILITY, agilityXP);
        skillXP.put(Skills.ATTACK, attackXP);
        skillXP.put(Skills.COMBAT, combatXP);
        skillXP.put(Skills.CONSTITUTION, constitutionXP);
        skillXP.put(Skills.CONSTRUCTION, constructionXP);
        skillXP.put(Skills.COOKING, cookingXP);
        skillXP.put(Skills.CRAFTING, craftingXP);
        skillXP.put(Skills.DEFENCE, defenceXP);
        skillXP.put(Skills.DUNGEONEERING, dungeoneeringXP);
        skillXP.put(Skills.FARMING, farmingXP);
        skillXP.put(Skills.FIREMAKING, firemakingXP);
        skillXP.put(Skills.FISHING, fishingXP);
        skillXP.put(Skills.FLETCHING, fletchingXP);
        skillXP.put(Skills.HERBLORE, herbloreXP);
        skillXP.put(Skills.HUNTER, hunterXP);
        skillXP.put(Skills.MAGIC, magicXP);
        skillXP.put(Skills.MINING, miningXP);
        skillXP.put(Skills.PRAYER, prayerXP);
        skillXP.put(Skills.RANGED, rangedXP);
        skillXP.put(Skills.RUNECRAFTING, runecraftingXP);
        skillXP.put(Skills.SLAYER, slayerXP);
        skillXP.put(Skills.SMITHING, smithingXP);
        skillXP.put(Skills.STRENGTH, strengthXP);
        skillXP.put(Skills.SUMMONING, summoningXP);
        skillXP.put(Skills.THIEVING, thievingXP);
        skillXP.put(Skills.WOODCUTTING, woodcuttingXP);

    }


    private void setName(String s) {
        name = s;
    }
    public String getName() {
        return name;
    }

    public int getSkillLevel(Skills skill) {
        return skills.get(skill); // LINE 90 <---------------------
    }

    public void setSkillLevel(Skills skill, int level) {
        skills.put(skill, level);
    }

    public int getSkillXP(Skills skill) {
        return skills.get(skill);
    }

    public void setSkillXP(Skills skill, int level) {
        skills.put(skill, level);
    }

}

SkillUtils.java:

代码语言:javascript
复制
package com.mcvigor.utils;

import com.mcvigor.RuneCraft;
import com.mcvigor.RunePlayer;
import com.mcvigor.Skills;

public class SkillUtils {


    public static int getChances(Skills skill, String player, int levelRequired) {
        RunePlayer rp = RuneCraft.players.get(player);
        int skillLevel = rp.getSkillLevel(skill); // LINE 12 <-------------
        if(skillLevel >= levelRequired) {
            return skillLevel - levelRequired;
        } else {
            return -1;
        }
    }

    public static boolean shouldBreakBlock(int chance, int levelRequired) {
        return chance >= RuneCraft.rand.nextInt((int)(levelRequired * 1.5));
    }
}

MiningListener.java:

代码语言:javascript
复制
package com.mcvigor.listeners;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;

import com.mcvigor.RuneCraft;
import com.mcvigor.Skills;
import com.mcvigor.utils.SkillUtils;

public class MiningListener implements Listener {

    RuneCraft plugin;

    public MiningListener(RuneCraft instance) {
        plugin = instance;
    }

    public boolean hasPickaxe(Player p) {
        final PlayerInventory i = p.getInventory();
        if(i.contains(Material.WOOD_PICKAXE) || i.contains(Material.STONE_PICKAXE) || i.contains(Material.GOLD_PICKAXE) || i.contains(Material.IRON_PICKAXE) || i.contains(Material.DIAMOND_PICKAXE)) {
            return true;
        }
        return false;
    }

    public boolean clickedBlockIsMineral(PlayerInteractEvent event) {
        if(event.getClickedBlock() != null && event.getClickedBlock().getType() != null) {  
            Material b = event.getClickedBlock().getType();
            if(b.equals(Material.CLAY) || b.equals(Material.GLOWING_REDSTONE_ORE) || b.equals(Material.REDSTONE_ORE) || b.equals(Material.LAPIS_ORE) || b.equals(Material.IRON_ORE) || b.equals(Material.BEDROCK) || b.equals(Material.COAL_ORE) || b.equals(Material.GOLD_ORE) || b.equals(Material.SPONGE) || b.equals(Material.EMERALD_ORE) || b.equals(Material.DIAMOND_ORE)) {
                return true;
            }
        }
        return false;
    }

    public boolean blockIsMineral(BlockBreakEvent event) {
        if(event.getBlock() != null && event.getBlock().getType() != null) {    
            Material m = event.getBlock().getType();
            if(event.getBlock() != null && m != null || m.equals(Material.CLAY) || m.equals(Material.GLOWING_REDSTONE_ORE) || m.equals(Material.REDSTONE_ORE) || m.equals(Material.LAPIS_ORE) || m.equals(Material.IRON_ORE) || m.equals(Material.BEDROCK) || m.equals(Material.COAL_ORE) || m.equals(Material.GOLD_ORE) || m.equals(Material.SPONGE) || m.equals(Material.EMERALD_ORE) || m.equals(Material.DIAMOND_ORE)) {
                return true;
            }
        }
        return false;
    }

    public boolean hasInventorySpace(Player p) {
        for(ItemStack i : p.getInventory().getContents()) {
            if(i == null || i.getType() == null || i.getType().equals(Material.AIR)) {
                return true;
            }
        }
        return false;
    }

    @EventHandler(ignoreCancelled = true)
    public void placeBlocks(BlockPlaceEvent event) {
        if(event.getPlayer().isOp()) return;
        event.setCancelled(true);
    }

    @EventHandler(priority=EventPriority.MONITOR)
    public void playerRClickOre(final PlayerInteractEvent event) throws InterruptedException { //Ore Interactions

        final Player p = event.getPlayer();

        if(event.getPlayer().isOp() || RuneCraft.busyPlayers.contains(p.getName())) return;

        if(!hasInventorySpace(p) && clickedBlockIsMineral(event) && event.getAction() == Action.LEFT_CLICK_BLOCK) {
            event.setCancelled(true);
            p.sendMessage(ChatColor.GRAY + "You do not have enough space in your inventory to mine this rock.");
        }

        if(clickedBlockIsMineral(event) && event.getAction() == Action.LEFT_CLICK_BLOCK && !hasPickaxe(p) && hasInventorySpace(p)) {
            event.setCancelled(true);
            RuneCraft.busyPlayers.add(p.getName());
            p.sendMessage(ChatColor.GRAY + "You need a " + ChatColor.DARK_RED + "pickaxe " + ChatColor.GRAY + "to mine this rock."); // ADD CHECKS FOR PICKAXE REQUIRED LEVEL TO USE
            RuneCraft.busyPlayers.remove(p.getName());
        }

        if(clickedBlockIsMineral(event) && event.getAction() == Action.RIGHT_CLICK_BLOCK) {

            final String clickedOreTypeNames = event.getClickedBlock().getType().toString().toLowerCase().replaceAll("_", " ").replaceAll("glowing redstone ore", "copper ore").replaceAll("redstone ore", "copper ore").replaceAll("lapis ore", "tin ore").replaceAll("bedrock", "silver ore").replaceAll("sponge", "mithril ore").replaceAll("emerald ore", "adamant ore").replaceAll("diamond ore", "runite ore");

            RuneCraft.busyPlayers.add(p.getName());
            p.sendMessage(ChatColor.GRAY + "You examine the rock for ores...");
            Bukkit.getScheduler().runTaskLater(plugin, new Runnable(){
                public void run() {
                    p.sendMessage(ChatColor.GRAY + "This rock contains " + ChatColor.DARK_RED + clickedOreTypeNames + ChatColor.GRAY + ".");
                    RuneCraft.busyPlayers.remove(p.getName());
                }
            }, 3*20L); // TODO: Change time

        }

    }

    @EventHandler(ignoreCancelled = true, priority=EventPriority.MONITOR)
    public void breakBlocks(final BlockBreakEvent event) { //MINING

        Player p = event.getPlayer();
        final String oreTypeNames = event.getBlock().getType().toString().toLowerCase().replaceAll("_", " ").replaceAll("glowing redstone ore", "copper ore").replaceAll("redstone ore", "copper ore").replaceAll("lapis ore", "tin ore").replaceAll("bedrock", "silver ore").replaceAll("sponge", "mithril ore").replaceAll("emerald ore", "adamant ore").replaceAll("diamond ore", "runite ore");
        final Material originalOre = event.getBlock().getType();

        if(p.isOp() || RuneCraft.busyPlayers.contains(p.getName())) return;

        //RequiredLevels
        int clayChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 1)) + 1);
        int copperChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 1)) + 1);
        int tinChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 1)) + 1);
        int ironChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 15)) + 1);
        int silverChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 20)) + 1);
        int coalChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 30)) + 1);
        int goldChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 40)) + 1);
        int mithrilChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 55)) + 1);
        int adamantChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 70)) + 1);
        int runiteChance = (RuneCraft.rand.nextInt(SkillUtils.getChances(Skills.MINING, event.getPlayer().getName(), 85)) + 1);

        if(!hasPickaxe(p) || !hasInventorySpace(p) || !blockIsMineral(event)) event.setCancelled(true);

        if(hasPickaxe(p) && blockIsMineral(event)) {

            if(!SkillUtils.shouldBreakBlock(clayChance, 1)) {
                event.setCancelled(true);
                p.sendMessage(ChatColor.DARK_RED + "Your mining level is not high enough to mine this rock.");
            }
            event.setCancelled(true);
            p.sendMessage(ChatColor.GRAY + "You swing your pick at the rock.");
            //ADD TIMER WITH PICKAXE TYPE + LEVEL + ORE TYPE MODIFIER HERE
            event.getBlock().setType(Material.COBBLESTONE);
            p.sendMessage(ChatColor.GRAY + "You manage to mine some " + ChatColor.DARK_RED + oreTypeNames + ChatColor.GRAY + ".");  
            event.getBlock().getDrops().clear();
            Bukkit.getScheduler().runTaskLater(plugin, new Runnable(){
                public void run() {
                    event.getBlock().setType(originalOre);
                }
            }, 5*20L); // TODO: Change time

        }

    }

}

有人知道怎么修复这个NPE吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-23 19:31:17

您的RunePlayer.getSkillLevel(Skills)方法(和getSkillXP())应该返回Integer而不是int

如果您的skills HashMap没有指定的技能,它将返回null。但是由于返回类型为intintInteger之间的自动装箱不能将null转换为int,因为null不是int的有效值。这样你就得到了NPE。

(为可读性而编辑)

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17260220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档