2013-12-10 95 views
1

我现在有一些例外,我一直在努力解决它们,所以任何关于如何修复它们的指南或建议都会很好,而不必依赖别人来帮助他们。 目前我有一个关于如何解决这个问题的建议,但是如果从长远来看如何找出问题的原因将会更好。跟踪NullPointerExceptions的最佳方式是什么?

class Egg extends Bee{ 
    protected void anotherDay() { 

     eat(); 
     if(age>=3) 
     { 
      HashMap<String, Hive> thisHive = Garden.GARDEN.getHiveMap(); 
      Larvae larvae = new Larvae(this.health, this.age); 
      thisHive.get("a").bees.set(thisHive.get("a").beeIndex, larvae); //-------LINE 27 
      //thisHive.get("a").replaceBee(larvae) Line 27 was origionally this throwing the same exception 

     } 
     age++; 
     System.out.println("Egg" + " age " + this.age + " health " + this.health); 

    } 
} 

import java.util.ArrayList; 

class Hive { 
    protected int honey; 
    protected int royalJelly; 
    protected int pollen; 
    public int beeIndex; // used to know what the index of bee you are in is 
    public boolean holdAdd; 
    ArrayList<Bee> bees = new ArrayList<Bee>(); 
    protected Hive(int honeyStart, int royalJellyStart, int pollenStart) 
    { 
     bees = new ArrayList<Bee>(); 
     this.setHoney(honeyStart); 
     this.setRoyalJelly(royalJellyStart); 
     this.setPollen(pollenStart); 
     System.out.println("hive made"); 
     System.out.println(honey + " honey"); 
     System.out.println(royalJelly + " royalJelly"); 
     System.out.println(pollen + " pollen"); 
     holdAdd = false; 
    } 
    //code removed ... 

    public void replaceBee(Bee addBee) { 
     bees.set(beeIndex, addBee); 
    } 

    // code removed 

    protected void anotherDay() { 
     int i = 0; 
     for(int k = 0; k < bees.size(); k++) 
     { 
      i++; 
      Bee bee = bees.get(k); 
      bee.anotherDay(); // ----------------LINE 144 
      beeIndex = i; 
     } 
     // code removed 
    } 
} 


public class Garden { 

    static HashMap<String, Hive> HiveMap = new HashMap<String, Hive>(); 
    public static final Garden GARDEN = new Garden(); 
    public static void main(String[] args) { 
      GARDEN.anotherDay(); //------------------LINE 21 
     } 
    } 

    //CODE REMOVED 

    public HashMap<String, Hive> getHiveMap() 
    { 
     return Garden.HiveMap; 
    } 
    // CODE REMOVED 


    protected void anotherDay() { 
     //CODE REMOVED 

     //should find all Hives and call anotherday() on them each 

     for(Hive currentHive : HiveMap.values()){ 
      currentHive.anotherDay(); //------------LINE 56 
     } 

     } 
     //CODE REMOVED 
} 
+8

堆栈跟踪给你当空指针发生线路。如果只能从特定行中的一个地方抛出空指针,那么您知道哪个变量为空并导致了异常。如果该行有多种可能性,调试器将有所帮助。然后,只需回溯调用堆栈即可找到null出现的位置。 – Tobb

+1

那么,如果您试图引用一个空对象,并且该对象可以为空,请在访问之前检查它是否为空。如果对象不能为null,那么你的代码中有一个逻辑错误条件,并且需要弄清楚为什么。 – OldProgrammer

+0

你的代码似乎与你的问题无关。他们之间有什么联系?你要求我们为你调试吗? – Raedwald

回答

4

如果您有堆栈跟踪,NullPointerException异常通常很容易用一些练习发现:它来自调用一个方法或一个对象,它是空的引用的属性。因此,查看报告的行并查看正在引用的对象。在你的例子中:

thisHive.get("a").bees.set(thisHive.get("a").beeIndex, larvae); 

可以thisHive为空吗? get("a")返回什么?它可以为空吗? (是的,因为如果没有找到键,映射返回null)。 bees可以为null吗?等等你通常可以通过查看代码来发现它,但调试器使它更容易。在行上设置一个断点,看看什么是空的。然后向后工作来理解为什么它是空的。

有一点需要注意的自动装箱的:如果你有声明为一个包装类(LongIntegerBoolean等)的变量,你引用它作为一种原始的,你会得到一个NPE:

private int getMyInt() { 
    Integer myInt = null; 
    return myInt; 
} 

private void doSomething() { 
    int i = getMyInt(); 
} 
5

NullPointerException是代码中您试图访问/修改尚未初始化的对象的情况。

因此理想情况下,您不应该修复NPE,而是需要确保您不在Null对象上操作/调用。

  • 几个场景是空使用
  • 同步的对象,它是空
  • 关键在于你会得到未初始化
  • 参数的方法传递的对象上的NPE
  • 调用方法散列表为空
  • 在单个语句中链接的方法调用

我们如何处理安全

1.更好的编码实践

如1:提高编码风格

String s=getValue(); 
// this is error prone 
if(s.equals("SOMEVALUE"){ 
} 
// Rather you can check for 
if("SOMEVALLUE".equals(s)){ 

} 

EG2:不要返回Null从对象返回类型,说如果你想要返回List,而不是返回null,您可以试试Collections.emptyList()

public List getEmpList(){ 
    // some operation 
    if(exp) { 
     return List 
    } 
    else{ 
     return Collections.emptyList(); //dont return null 
    } 

    } 

2.提供足够的测试覆盖率。

NPE是RunTimeException,您应该能够从测试类中捕获大部分RTE。

3劝阻空参数

传,但也有一些,你必须支持NPE

约书亚布洛赫有效的Java地说:“可以说,所有的错误 方法调用熬下至非法参数或非法状态, 但其他例外标准用于某些非法 参数和状态。如果调用者传递一些参数为null 其中空值禁止,会议决定了 NullPointerException异常被抛出,而不是IllegalArgumentException异常。”

0

我的建议是保持线短,不要让太多的嵌套直列呼叫。如果在下面的行中出现错误,将很难找出哪些对象为空。

thisHive.get("a").bees.set(thisHive.get("a").beeIndex, larvae) . 
+0

origionally那行是thisHive.get(“a”)。replaceBee(幼虫);但它在进入replaceBee()函数之前抛出nullException,不知道发生了什么,我试图以不同的方式来查看发生了什么。如果在这种情况下KeySet为null,KeySet是什么导致null异常 – user1642671

1

您可以在调试器中为NPE设置一个断点,以便在它们出现时向您显示堆栈帧内容(涉及的字段和对象)时始终停止。这里是你如何能与理念做到这一点:

enter image description here

enter image description here

相关问题