2013-12-10 98 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

相關問題