2016-07-13 18 views
0

Das Programm wird ohne Fehler ausgeführt, wenn ich Thread von main() starten möchte, aber warum ich NullponderException bekomme, wenn ich Thread vom Konstruktor starten will.NullPointerException Beim Starten von Konstruktor

class MyThread extends Thread 
{ 

    static MyThread obj; 
    MyThread() 
    { 
     obj.start(); 
     for(int i=1;i<20;i++) 
     System.out.println("getName:"+obj.currentThread().getName()); 
    } 

    public void run() 
    { 
     for(int i=1;i<20;i++) 
    System.out.println("getName:"+obj.currentThread().getName()); 
    } 


    public static void main(String... s) 
    { 
     obj=new MyThread(); 

    } 
} 
+2

Obj muss initialisiert werden. – Sampada

Antwort

3

Das Problem ist, dass Ihr Code die Dinge in der falschen Reihenfolge macht. Wenn Sie

obj = new MyThread(); 

sagen, dass der Code tut dies:

  1. Erstellen Sie ein neues MyThread Objekt. Das Erstellen des neuen Objekts umfasst das Ausführen des Konstruktors. Der Wert new MyThread() wird eine Referenz auf das neue Objekt sein.
  2. Weisen Sie diesen Verweis obj zu.

Das funktioniert nicht, weil Schritt 1 versucht obj zu verwenden, bevor sie einen Wert in Schritt bekommen 2.

Die Lösung (glaube ich) ist zu erkennen, dass, wenn Sie im Konstruktor sind this ist eine Referenz auf das zu erstellende Objekt. Da das scheint zu sein, was Sie obj sein wollen, können Sie Ihr Programm ausführen erhalten, indem

obj.start(); 

mit

this.start(); 

oder äquivalent zu ersetzen, nur

start(); 

Ich habe versucht, das und es scheint zu funktionieren. Allerdings empfehle ich nicht, dies in einem echten Programm zu tun. Das Starten eines Thread-Objekts, bevor der Konstruktor fertig ist, erscheint mir gefährlich. (Was würde passieren, wenn nach dem Aufruf start() der Rest des Konstruktors eine Ausnahme auslöst? Ich müsste nachsehen, um die genaue Semantik herauszufinden, aber das würde bedeuten, dass Sie einen Thread ausführen, dessen Konstruktion nie stattgefunden hat Was ist, wenn die run() Methode des Threads versucht, auf Instanzvariablen zuzugreifen, die erst später im Konstruktor gesetzt werden?) Wenn Sie denken, dass Sie so etwas wollen, dann müssen Sie höchstwahrscheinlich Ihr Design überdenken. Ein einfacher Weg, dies zu umgehen, ist jedoch die Bereitstellung einer statischen Factory-Methode (die andere Vorteile hat), die einen privaten Konstruktor, , dann Aufrufe start() auf das neue Objekt [dessen Konstruktion erfolgreich abgeschlossen hat] dann tut nichts Ansonsten möchten Sie nach dem start() tun.

[P.S. Ich sage "Ich denke" das ist die richtige Lösung, weil es nicht ganz klar ist, was Sie erreichen wollen.]

Verwandte Themen