2016-07-13 8 views
0

main()からスレッドを開始しようとしているときにプログラムが実行されていますが、コンストラクタからスレッドを開始しようとしたときにNullPointerExceptionが発生します。NullPointerExceptionコンストラクタから開始するとき

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を初期化する必要があります。 – Sampada

答えて

3

問題は、コードの順序が間違っていることです。あなたは、コード

obj = new MyThread(); 

を言うとき、このん:

  1. は新しいMyThreadオブジェクトを作成します。新しいオブジェクトを作成するには、コンストラクタを実行する必要があります。 new MyThread()の値は、新しいオブジェクトへの参照になります。
  2. objにこの参照を割り当てます。

これは(私が思う)、それは、ステップ2

で値を取得する前に解決策をobjを使用するステップ1しようとするため、動作しません。あなたは、コンストラクタにいるとき、それを実現することです、thisは、作成されるオブジェクトへの参照です。それはあなたがするobjを望むもののようですので、あなただけの

start(); 

私が試した、同等

this.start(); 

か、と

obj.start(); 

を交換することにより実行するようにプログラムを得ることができますこれはうまくいくと思われる。しかし、私は実際のプログラムでこれを行うことをお勧めしません。コンストラクタが完了する前にスレッドオブジェクトを開始すると、危険なものとして私に当たります。 (start()呼び出しの後に、コンストラクタの残りの部分が例外をスローするとどうなりますか?正確な意味を理解するためにはそれを調べなければなりませんが、スレッドのrun()メソッドが、後でコンストラクタで設定されないインスタンス変数にアクセスしようとした場合はどうなりますか?)このようなことが必要と思われる場合は、デザインを再考する必要があります。しかし、これを回避する簡単な方法は、プライベートコンストラクタを呼び出す静的ファクトリメソッド(他の利点があります)を提供することです。start()は新しいオブジェクト[建設が成功しました]、それ以外の場合は、start()の後にやりたいことです。

[P.S.私はあなたが達成しようとしていることが完全にはっきりしていないので、これは正しい解決策だと思っています。

関連する問題