2016-10-20 1 views
2

Ich bin Debuggen einer Anwendung, die entworfen wurde, um einen Fall von foo, der null ist. Beim Überprüfen eines Protokolls aus der Produktion wurde jedoch ein NullPointerException ausgelöst, der versuchte, auf eine Methode von foo zuzugreifen, nachdem sie ordnungsgemäß verarbeitet werden sollte.Unter keinen Umständen kann `foo == null` falsch sein, wenn` foo` tatsächlich null ist?

es sieht aus wie diese

if (foo == null) { 
    throw new GracefulException(); 
} 

Bar bar = foo.getBar(); 

Also mit diesem Code an Ort und Stelle, ein NullPointerException in der Produktion aufgetreten ist, wenn foo.getBar() Aufruf.

Meine Frage ist einfach das: Hat jemand jemals von funky Verhalten gehört, wie dies geschieht oder sogar möglich ist? Und wenn ja, was könnte das verursachen?

+3

Nein. Dies ist nicht möglich. Mein Geld steht auf einem schlecht geschriebenen "Versuch ... Fang". –

+1

Können Sie eine vollständige Stapelverfolgung hinzufügen? – NilsH

+0

@NilsH Der Code, den ich in meiner Frage geschrieben habe, ist ein stark abstrahiertes Beispiel für den tatsächlichen Produktionscode. Ein Stacktrace wäre nutzlos, wenn ich den Beispielcode nicht so weit verbessern würde, dass er den tatsächlichen Code widerspiegelt, und die Zeilennummern geändert und vertrauliche Informationen aus dem Stacktrace entfernt hat. – zero01alpha

Antwort

7

Überprüfen Sie den Aufrufstapel; das könnte von innen kommen getBar().

Auch wenn foo keine lokale Variable ist, könnte ein anderer Thread sie auf null nach dem if setzen.

+0

'foo' ist eine lokale Variable, aber sie bezieht ihren Wert von einer statischen Hilfsklasse, die Sitzungsdaten abruft. Dies ist eine Webanwendung, die auf einem Tomcat-Server ausgeführt wird. Ich bin mir nicht sicher, ob ich den Aufrufstack von 'getBar()' überprüfen kann, weil der einzige Beweis dafür ist, dass eine Protokolldatei nur den Stack-Trace einer unbehandelten Ausnahme ablegt. Der einzige Grund, warum ich weiß, dass es von 'foo.getBar()' kommt, liegt daran, dass dies nur in der Zeilennummer geschieht, die im Stack-Trace angegeben ist. – zero01alpha

+3

@ zero01alpha Wenn 'foo' eine lokale Variable ist, kann sie zwischen diesen Codezeilen nicht aktualisiert werden. –

+0

Wie könnte etwas von 'getBar()' kommen, wenn der Versuch, 'getBar()' aufzurufen, zur 'NullPointerException' führt? Verzeihen Sie meinen Mangel an Wissen. – zero01alpha

1

Nr foo == null kann nie false sein, wenn foonull ist.

Es konnten diese möglichen Fälle sein:

  1. Ihre Anwendung ist multi-threaded und foo ist ein gemeinsames Feld, das nicht richtig synchronisiert ist. Wenn dies der Fall ist, ist eine Synchronisation erforderlich. Da foo eine lokale Variable ist, ist dieser Fall hier nicht anwendbar.
  2. Ausnahme kommt von innen foo.getBar(). Dieser Fall kann leicht durch das Generieren der Stack-Trace identifiziert werden. Überprüfen Sie, ob der Methodenname in der Stack-Trace vorhanden ist.

Betrachten wir zum Beispiel unten Code:

public class Temp { 
    public static void main(String[] args) { 
     new Temp().functionA(); 
    } 

    void functionA() { 
     Foo foo = new Foo(); 
     //foo = null; //Line 1 
     String str = foo.getBar(); 
    } 
} 

class Foo { 
    Object x = new Object(); 

    public String getBar() { 
     //x = null; //Line 2 
     return x.toString(); 
    } 
} 

Wenn foo ist null (Linie 1 nicht kommentiert), Stack-Trace wäre wie:

Exception in thread "main" java.lang.NullPointerException 
at Temp.functionA(Temp.java:9) 
at Temp.main(Temp.java:3) 

Wenn xnull ist (Zeile 2 nicht kommentiert), Stack-Trace wäre wie folgt:

Exception in thread "main" java.lang.NullPointerException 
at Foo.getBar(Temp.java:16) 
at Temp.functionA(Temp.java:8) 
at Temp.main(Temp.java:3) 
1

Wenn foo.getBar() im Stack-Trace erwähnt wird, wird die Ausnahme innerhalb dieser Methode ausgelöst und Sie suchen an falscher Stelle.

Wenn der Anfang des Stack-Trace die Methode ist, die diesen foo.getBar()-Aufruf enthält, ist foonull.

Da Sie schreiben, dass foo eine lokale Variable ist, dann ist dies nicht aufgrund einiger anderer Thread zu stören - ein anderer Thread nie den Wert Ihrer lokalen Variablen festlegen können (die meisten es tun kann, ist, ändern Sie es Inhalt ist).

  • Sie sicher, dass keine Aussage foo zu null zwischen der Kontrolle und dem Methodenaufruf gibt es einstellen.
  • überprüfen, dass es keine Möglichkeit gibt, den Scheck (das heißt, dass der Scheck nicht in einem bedingten Block)
  • Überprüfen Sie, dass es keinen Block abfangen GracefulException zwischen der Kontrolle und den Methodenaufruf zu vermeiden.
Verwandte Themen