NullPointerException从构造函数开始

时间:2016-07-13 02:33:11

标签: java multithreading nullpointerexception

当我尝试从main()启动Thread时,程序正在运行而没有任何错误但是当我尝试从构造函数启动Thread时,为什么我得到NullponterException。

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

   }
}

1 个答案:

答案 0 :(得分:3)

问题是您的代码以错误的顺序执行操作。当你说

obj = new MyThread();

代码执行此操作:

  1. 创建一个新的MyThread对象。创建新对象包括执行构造函数。 new MyThread()的值将是对新对象的引用。
  2. 将此引用分配给obj
  3. 这不起作用,因为步骤1在步骤2中获取值之前尝试使用obj

    解决方案(我认为)是要意识到,当你在构造函数中时,this是对正在创建的对象的引用。由于这似乎是您想要的obj,您可以通过替换

    来运行您的程序
    obj.start();
    

    this.start();
    

    或等同于

    start();
    

    我试过这个似乎有效。但是,我建议在真实程序中执行此操作。在构造函数完成之前启动一个线程对象会让我感到危险。 (如果在start()调用之后,构造函数的其余部分抛出异常,会发生什么?我必须查找确切的语义,但这意味着你正在运行一个线程如果线程的run()方法试图访问直到构造函数后期才设置的实例变量,该怎么办?如果你认为你想要这样的东西,那么很可能你需要重新考虑你的设计。但是,解决此问题的一种简单方法是提供一个静态工厂方法(具有其他优点),该方法调用私有构造函数,然后调用新对象[其构造具有的start()已成功完成],然后start()后执行您要执行的任何其他操作。

    [P.S。我说“我认为”这是正确的解决方案,因为它并不完全清楚你要完成的是什么。]