2012-01-31 16 views
5

Szukam szybkiego sposobu ustalania, która część wartości chain jest pusta.Znajdowanie wartości null w łańcuchu wywołań metod

przykład zilustrować topnienia:

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

To oczywiście rzut NullPointerException. (Wiem, jak zmienić kod, aby było jasne, jaka część łańcucha rzuciła się na NullPointerException, ale chciałbym go jakoś wymyślić z istniejącym kodem.)

+1

Co chcesz wydrukować? Hashcode łańcucha zawierającego zero? –

+0

Chcę coś jak "c1.returnChain(). ReturnChain() zwrócił null". –

+0

@ChristianJonassen: Szukasz rozwiązania dla tego konkretnego fragmentu kodu lub czegoś bardziej ogólnego, gdy wykonujesz sekwencję połączeń z dowolnymi funkcjami? – Dawood

Odpowiedz

2

W ślad stosu dla typowego NPE, dostaniesz numer wiersza przyszło na. Więc zakładając System.out.println(c1.returnChain().returnChain().returnChain().returnChain()); jest na linii 144 (tylko podniósł, że losowo) swój NPE stos ślad powinien wyglądać mniej więcej tak:

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

więc, jeśli umieścisz swoje połączenia łańcucha na wielu liniach, to powinien pokazać, gdzie wyjątek.

Napisałem ten mały przykład:

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

i dała mi NPE mówi: co bla.Something.main (Something.java:18) - dokładnie tam, gdzie NPE wystąpił w łańcuchu.

Zrzut ekranu ...

Showing what this would look like...

+0

Próbowałem tego samego, ale to nie działało dla mnie! Zanotowałem pierwszą linię instrukcji, w której wyrzucono NPE. – thermz

+0

Czy ktoś chce wyjaśnić sprawę? Nie mam nic przeciwko temu, że się mylę, ale przynajmniej chciałbym wyjaśnić. – Dave

+0

@thermz, czy mógłbyś opublikować kod od kiedy to wypróbowałeś i to nie zadziałało? – Dave

0

Może nie rozumiem tego, ale co o tylko returnChain() == null?

0

Można dodać do Chain zmiennej klasy jak position za określanie położenia elementu w łańcuchu:

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

Oczywiście to nie wątku bezpieczne i wygląda dziwnie. Ale powinien wypisać pozycję o wartości zerowej. Prostsza wersja:

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

Nie sądzę, że Christian Jonassen potrzebuje rozwiązania dla tego konkretnego fragmentu kodu (co jest oczywiście przykładem), myślę, że szuka rozwiązania, aby zawsze znaleźć NPE w "łańcuchowym" wywołaniu metod ... coś jak 'this.getTown(). getAvenue(). getNumber(). getFloor()' jeśli avenue ma wartość null nie ma dobrego rozwiązania, aby zawsze znaleźć miejsce, w którym NPE jest wyrzucane .. chyba że nie chcesz próbować & wyłapać każdego wywołania ... – thermz

+0

Dla tego scenariusza możesz użyć 'npe.getStackTrace() [0] .getMethodName()'. Oczywiście nie pomaga tutaj. –

+0

Niestety nie, w tej sytuacji (właściciel kodu pytania) wywołanie 'npe.getStackTrace() [0] .getMethodName()' zwróci "główny" – thermz

2

Dla danego kawałka kodu, który masz, spróbuj dodać następującą metodę do klasy 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; 
    } 

Można go używać jako to:

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

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

To byłoby pr int:

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

bez modyfikowania klasy Chain, można to zrobić, aby dowiedzieć się, która część jest zerowy:

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 

Albo można po prostu złapać wyjątku null pointer wydrukować zerowy

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  
Powiązane problemy