创建线程的NullPointerException

时间:2012-03-29 12:26:32

标签: java multithreading console

我有一个简单的练习,我调用一个Thread,然后调用run()方法。

但是我得到一个NullPointerException。

努力弄清楚为什么会出现这种异常。

package practice;
import java.util.Date;
import java.text.SimpleDateFormat;


class IdDisplay implements Runnable
{
    String idNumber;
    IdDisplay(String ID)
    {
        this.idNumber = ID;

    }
    char [] idMine = this.idNumber.toCharArray();
    public void run()
    {
        for(int i = 0; i < idMine.length; i++)
        {
            System.out.print(idMine[i] + " ");
            try
            {
                Thread.sleep(1000);
            }
            catch(InterruptedException in){}


        }
    }       
}
public class Practice
{
    public static void main(String[]args)
    {


        String name = "Arian";
        String age = "38";
        String id = "7401195021087";

        int ageInt;
        int year;
        int yearBorn;

        System.out.println("Welcome " + name + " your age is " + age + " and your ID number " + id);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        Date date = new Date();

        year = Integer.parseInt(sdf.format(date));
        ageInt = Integer.parseInt(age);
        yearBorn = year - ageInt;
        System.out.println("You were born in " + yearBorn);

        IdDisplay idClass = new IdDisplay(id);
    Thread tt = new Thread(idClass);
    tt.start(); 



    }
}   

为什么我会收到此NullPointerException。

此致

7 个答案:

答案 0 :(得分:4)

您声明了两个实例字段:

String idNumber;

char [] idMine = this.idNumber.toCharArray();

第二个的初始值设定项假设第一个不是null,它是开头的,因此是例外。在进入构造函数之前处理实例初始值设定项。

相反,将初始化移动到构造函数中:

IdDisplay(String ID)
{
    this.idNumber = ID;
    this.idMine = this.idNumber.toCharArray();
}

还强烈建议在一个地方声明你的所有字段(我更喜欢它们在课程的开头,但你放在它们的位置是一个风格问题;你把它们放在一起是一个更实质性的维护考虑因素)。 (注意一般规则:在支持访问器的字段的情况下,有一个参数用于声明访问器旁边的字段。)事物之间的一些垂直空格可能很有用。

完整更新的IdDisplay课程:

class IdDisplay implements Runnable
{
    String  idNumber;
    char [] idMine;

    IdDisplay(String ID)
    {
        this.idNumber = ID;
        this.idMine = this.idNumber.toCharArray();
    }

    public void run()
    {
        for(int i = 0; i < idMine.length; i++)
        {
            System.out.print(idMine[i] + " ");
            try
            {
                Thread.sleep(1000);
            }
            catch(InterruptedException in){}
        }
    }       
}

答案 1 :(得分:1)

问题在于:

char [] idMine = this.idNumber.toCharArray();

此行在调用构造函数之前执行,您在其中初始化this.idNumber

建议更改:

String idNumber;
char [] idMine;

IdDisplay(String ID)
{
    this.idNumber = ID;
    idMine = this.idNumber.toCharArray();
}

答案 2 :(得分:1)

char [] idMine = this.idNumber.toCharArray(); 

此声明位于类范围内,此时this.idNumber是尚未分配的字符串对象。将其弹出到run()方法中。

答案 3 :(得分:1)

char [] idMine = this.idNumber.toCharArray();

尝试在

之前初始化
String idNumber;

并给你一个NPE。

答案 4 :(得分:1)

移动这一行:

char [] idMine = this.idNumber.toCharArray();

到构造函数(在设置idNumber之后)。在当前位置,当您创建IdDisplay的实例时,它会被初始化,并且由于idNumber未初始化,您将获得异常。

答案 5 :(得分:1)

您的空指针异常很可能来自此行:

char [] idMine = this.idNumber.toCharArray();

这是因为你在构造函数中初始化this.idNumber。但是,在this.idNumber仍然为null的时候,idMine将被更早地初始化。

答案 6 :(得分:1)

你已经创建了两个实例所以它会给出空指针异常。 实际上在你的代码中,在调用构造函数之前发生的char数组变量是初始化的,因此它始终为null。

尝试下面一个。

class IdDisplay implements Runnable
{
    String idnumber;
    char[] idMine;
    public  IdDisplay(String ID)
    {
        idnumber=ID;
        idMine = idnumber.toCharArray();
    }

    public void run()
    {
        for(int i = 0; i < idMine.length; i++)
        {
            System.out.print(idMine[i] + " ");
            try
            {
                Thread.sleep(1000);
            }
            catch(InterruptedException in){}


        }
    }       
}
public class Practice
{
    public static void main(String[]args)
    {


        String name = "Arian";
        String age = "38";
        String id = "7401195021087";

        int ageInt;
        int year;
        int yearBorn;

        System.out.println("Welcome " + name + " your age is " + age + " and your ID number " + id);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        Date date = new Date();

        year = Integer.parseInt(sdf.format(date));
        ageInt = Integer.parseInt(age);
        yearBorn = year - ageInt;
        System.out.println("You were born in " + yearBorn);

        IdDisplay idClass = new IdDisplay(id);
        Thread tt = new Thread(idClass);
        tt.start(); 
    }
}