为什么有些字符串(例如topStudent1)必须设置为null,而其他字符串(例如name1)则不能,以避免编译错误?为什么有些双打(例如highScore)必须设置为0,而其他(例如score1)则不能,以避免编译错误?
public class Exercise05_09 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of students: ");
int numOfStudents = input.nextInt();
String name1;
String name2;
String topStudent1 = null;
String topStudent2 = null;
double score1;
double score2;
double highScore = 0;
double nextHighScore = 0;
int count = 2;
while (count <= numOfStudents) {
if (count == 2) {
System.out.println("Enter a student name: ");
name1 = input.next();
System.out.println("Enter a student score: ");
score1 = input.nextDouble();
System.out.println("Enter a student name: ");
name2 = input.next();
System.out.println("Enter a student score: ");
score2 = input.nextDouble();
if (score1 > score2) {
highScore = score1;
topStudent1 = name1;
nextHighScore = score2;
topStudent2 = name2;
}
else {
highScore = score2;
topStudent1 = name2;
nextHighScore = score1;
topStudent2 = name1;
}
}
else {
System.out.println("Enter a student name: ");
name1 = input.next();
System.out.println("Enter a student score: ");
score1 = input.nextDouble();
if (score1 > highScore) {
nextHighScore = highScore;
highScore = score1;
topStudent2 = topStudent1;
topStudent1 = name1;
}
else if (score1 > nextHighScore) {
nextHighScore = score1;
topStudent2 = name1;
}
}
count++;
}
System.out.printf("Top two students:\n%s's score is %3.1f\n%s's score is %3.1f\n", topStudent1, highScore, topStudent2, nextHighScore);
}
}
谢谢!
答案 0 :(得分:6)
所有变量在访问之前必须明确分配(JLS §16),编译器会验证这一点:
每个局部变量(§14.4)和每个空白
final
字段(§4.12.4,§8.3.1.2)必须具有明确分配的值发现其价值的访问权。
由于while
循环可能根本不执行(例如用户输入1
),因此在topStudent1
语句中使用4个变量(例如printf
)需要变量初始化在 while循环之外。
这样的初始化不必在声明行上,但在那里进行更简单。
相比之下,其他变量(例如name1
)不会在while
循环之后使用,而是仅在循环内部使用,并且在它们之前明确分配使用。
答案 1 :(得分:2)
让我们以编译器的方式来看程序(当然是以高度简化的方式)。我们看到的第一件事是变量声明,其中一些初始化它们的变量。
之后是while
循环。一般规则是while
循环执行未知次数,包括零。因此,我们必须假设可能它根本不会执行,这意味着在其中分配的任何变量可能根本不会被分配。
最后,我们有一个输出语句,它使用了四个变量:topStudent1
,topStudent2
,highScore
和nextHighScore
。这些正是您发现需要初始化的那些。 (实际上,他们只需要在本声明之前的某处分配。)
那是怎么回事?由于编译器知道它需要在这四个变量中的每一个中都有一个值来支持printf
,因此它需要保证这些变量已被分配到某处。在while
循环内部分配不计,因为(就编译器所知),while
循环根本不会执行。如果在声明它们时没有初始化它们,并且没有以编译器识别的方式分配它们,那么在声明它们和使用它们之间总会发生它们,编译器会采用保守的视图并确定它们可能未初始化。
答案 2 :(得分:1)
原因很简单,你需要保证你使用的某些值不会爆炸你的应用程序因为没有初始化异常。
当你这样做时:
System.out.printf("Top two students:\n%s's score is %3.1f\n%s's score is %3.1f\n", topStudent1, highScore, topStudent2, nextHighScore);
然后你使用变量并将它们作为参数传递,但它们没有被初始化,所以方法printf,不知道在编译时打印什么是goint,因此必须将它们初始化为某些东西(在这种情况下) null也可以接受。)
答案 3 :(得分:1)
这是因为您需要设置的那些是if和else块,编译器不确定它们是否会被初始化以便停止错误它会强制您初始化它们。不需要初始化的那些在if / else之外,因此它们将被声明。我希望有帮助
澄清编译器可以看看它们是否肯定会通过你的逻辑进行初始化,如果只有它发生的可能性,它将确保它不会通过强制你声明它来抛出空。
答案 4 :(得分:1)
答案 5 :(得分:0)
标准规则是,
本地变量/实例(在方法内部声明)必须是 在使用之前初始化。
到目前为止,在使用之前,必须先通过0
或some value
或null
对其进行初始化。