2012-01-31 12 views
5

我正在尋找快速確定chain的哪部分爲空的方法。在方法調用鏈中查找空值

例如來說明這一點:

public class Chain { 
    private Chain chain; 

    public Chain returnChain() { 
     return chain; 
    } 

    public void addChain(Chain chain) { 
     this.chain=chain; 
    } 

    public String toString() { 
     return "Hello!"; 
    } 

    public static void main(String[] args) { 
     Chain c1 = new Chain(); 
     c1.addChain(new Chain()); 

     System.out.println(c1.returnChain().returnChain().returnChain().returnChain()); 
    } 
} 

這顯然會拋出一個NullPointerException。 (我知道如何改變代碼,以明確鏈條的哪個部分投擲了NullPointerException,但我想用一些方法來解決它與現有的代碼。)

+1

你想要輸出什麼?包含null的鏈的哈希碼? – 2012-01-31 21:37:56

+0

我想要類似「c1.returnChain()。returnChain()返回null」。 – 2012-01-31 21:41:02

+0

@ChristianJonassen:你是在尋找一個針對這段特定代碼的解決方案,或者是在尋找某種更通用的方法來製作對任意函數的調用序列? – Dawood 2012-01-31 21:58:59

回答

2

在一個典型的NPE堆棧跟蹤,你給了它發生的行號。因此,假設System.out.println(c1.returnChain().returnChain().returnChain().returnChain());上線144(剛撿到的,它隨機)您的NPE堆棧跟蹤應該是這個樣子:

java.lang.NullPointerException 
    at your.package.Chain(Chain.java:144) 

所以,如果你把多條線路上的鏈調用,它應該告訴你其中的例外是。

我寫了這個小例子:

package bla; 

public class Something { 
    public static int count = 0; 
    public Something get() { 
     if(count == 2) { 
      return null; 
     } 
     ++count; 
     return new Something(); 
    } 

    public static void main(String[] args){ 
     Something something = new Something(); 
     Something test = something.get() 
           .get() 
            .get() 
             .get() // Should throw NPE 
              .get() 
               .get(); 
    } 
} 

而且它給我的NPE說:在bla.Something.main(Something.java:18) - 究竟在何處NPE發生在鏈。

屏幕截圖...

Showing what this would look like...

+0

我嘗試過,但它沒有爲我工作!我記錄了NPE拋出的istruction的第一行 – thermz 2012-01-31 21:54:32

+0

有人在意解釋downvote嗎?我不介意,如果我錯了某些事情,但至少我想要一個解釋。 – Dave 2012-01-31 22:02:01

+0

@thermz,你可以發佈你試過的代碼嗎?它不起作用? – Dave 2012-01-31 22:13:07

0

也許我沒有得到它,但什麼大約只是returnChain() == null

0

您可以添加到Chain類變量一樣position爲determing在鏈元素的位置:

public class Chain { 
    private Chain chain; 
    private int position; 

    public Chain returnChain() { 
     if (chain == null) { 
      System.out.println(position + " chain is null"); 
     } else { 
      chain.position = position + 1; 
     } 
     return chain; 
    } 

    public void addChain(Chain chain) { 
     this.chain=chain; 
    } 

    public String toString() { 
     return "Hello!"; 
    } 

    public static void main(String[] args) { 
     Chain c1 = new Chain(); 
     c1.addChain(new Chain()); 
     c1.position = 0; 
     System.out.println(c1.returnChain().returnChain().returnChain().returnChain()); 
    } 
} 

當然它不是線程安全的,看起來怪怪的。但是應該寫出null的位置。 簡單的版本:

public int findPositionOfNullChain(Chain chain) { 
    int position = 0; 
    while (chain != null) { 
     chain = chain.returnChain(); 
     position++; 
    } 
    return position; 
} 
+3

我不認爲Christian Jonassen需要針對這段代碼的解決方案(這顯然是一個例子),我認爲他正在尋找一種解決方案來總是在「鏈式」調用方法中找到NPE。例如'this.getTown()。getAvenue()。getNumber()。getFloor()'如果通道爲空,沒有好的解決方案來總是在哪裏發現NPE ..除非你不想嘗試和捕獲每個通話... – thermz 2012-01-31 21:52:49

+0

對於這種情況,您可以使用'npe.getStackTrace()[0] .getMethodName()'。當然,這裏沒有幫助。 – 2012-01-31 22:08:19

+0

不幸的是,在這種情況下(問題的代碼的所有者)調用'npe.getStackTrace()[0] .getMethodName()'將返回「主」 – thermz 2012-01-31 22:16:59

2

對於代碼的特定部分,你有,嘗試添加下面的方法到您Chain類:

public static Chain checkChainSequence(Chain first, int count) { 
     Chain thisChain = first; 
     StringBuilder out = new StringBuilder("firstChain"); 
     for (int i = 0; i < count; i++) { 
      Chain nextChain = thisChain.returnChain(); 
      out.append(".returnChain()"); 
      if (nextChain == null) { 
       out.append(" returned null"); 
       System.out.println(out); 
       return null; 
      } 
      thisChain = nextChain; 
     } 
     return thisChain; 
    } 

你可以使用它作爲如下:

Chain c1 = new Chain(); 
    c1.addChain(new Chain()); 

    // To check c1.returnChain().returnChain().returnChain(): 
    Chain.checkChainSequence(c1, 3); 

This would pr INT:

firstChain.returnChain().returnChain() returned null 
0

,而無需修改鏈類,你可以做到這一點,找出哪些部分是空:

Chain c1 = new Chain(); 
c1.addChain(new Chain()); 
Chain preNullChain = c1; 
Chain returnedChained = null; 

while ((returnedChained = preNullChain.returnChain()) != null) { 
    preNullChain = returnedChained; 
} 
//here, preNullChain is the last Chain that is not null 

或者,你可以捕捉空指針異常打印空

Chain returnedChain = null; 
Chain c1 = new Chain(); 
c1.addChain(new Chain()); 
try { 
returnedChain = c1.returnChain().returnChain().returnChain().returnChain(); 
} catch (NullPointerException e) { 
} 
System.out.println(returnedChain); //now here will print null as what you asked for