2012-01-31 9 views
5

Sto cercando un modo rapido per capire quale parte di uno chain è nullo.Ricerca del valore null in una catena di chiamata del metodo

Un esempio per illustrare il punto:

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()); 
    } 
} 

Ciò, ovviamente, gettare un NullPointerException. (So ​​come modificare il codice per rendere evidente quale parte della catena ha gettato il NullPointerException, ma mi piacerebbe un modo per capirlo con il codice esistente.)

+1

Cosa vuoi come output? Hashcode della catena contenente null? –

+0

Voglio qualcosa come "c1.returnChain(). ReturnChain() restituito null". –

+0

@ChristianJonassen: stai cercando una soluzione per questo particolare pezzo di codice o qualcosa di più generico in cui stai facendo una sequenza di chiamate a funzioni arbitrarie? – Dawood

risposta

2

Nella traccia dello stack per un NPE tipico, si è dato il numero di riga si è verificato su. Quindi, supponendo System.out.println(c1.returnChain().returnChain().returnChain().returnChain()); è on line 144 (appena raccolte che casualmente) il vostro NPE dello stack trace dovrebbe essere simile:

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

Quindi, se si mette la chiamata in serie su più righe, si dovrebbe mostrare dove l'eccezione è.

Ho scritto questa piccola premessa:

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(); 
    } 
} 

e mi ha dato la NPE dice: a bla.Something.main (Something.java:18) - esattamente dove il NPE si è verificato nella catena.

colpo dello schermo ...

Showing what this would look like...

+0

Ho provato lo stesso ma non ha funzionato per me! Ho registrato la prima riga dell'istruction dove viene lanciato il NPE – thermz

+0

Qualcuno si preoccupa di spiegare il downvote? Non mi dispiace se mi sbaglio su qualcosa, ma mi piacerebbe almeno una spiegazione. – Dave

+0

@thermz, potresti pubblicare il codice da quando lo hai provato e non ha funzionato? – Dave

0

Forse non lo capisco, ma cosa a proposito di solo returnChain() == null?

0

è possibile aggiungere al Chain variabile di classe come position per posizione dell'elemento determing a catena:

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()); 
    } 
} 

Naturalmente non è thread-safe e sembra strano. Ma è necessario scrivere la posizione di null. versione più semplice:

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

Non credo che Christian Jonassen abbia bisogno di una soluzione per questo particolare pezzo di codice (che è chiaramente un esempio), penso che stia cercando una soluzione per trovare sempre un NPE in una chiamata "concatenata" di metodi .. qualcosa come 'this.getTown(). getAvenue(). getNumber(). getFloor()' se avenue è nullo non c'è una buona soluzione per trovare sempre dove viene generata NPE .. a meno che tu non voglia provare e catturare ogni chiamata ... – thermz

+0

Per tale scenario è possibile utilizzare 'npe.getStackTrace() [0] .getMethodName()'. Non aiuta qui, ovviamente. –

+0

Purtroppo no, in questa situazione (il proprietario del codice del problema) chiamare 'npe.getStackTrace() [0] .getMethodName()' restituirà "principale" – thermz

2

Per la particolare pezzo di codice che avete, prova ad aggiungere il seguente metodo alla classe 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; 
    } 

è possibile utilizzarlo come segue:

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

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

Questo sarebbe pr Int:

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

senza modificare la classe di catena, si può fare questo per scoprire quale parte è nullo:

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 

Oppure si può semplicemente intercettare l'eccezione puntatore nullo per stampare nulla

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  
Problemi correlati