我有一个简单的练习,我调用一个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。
此致
答案 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();
}
}