java为什么某些变量必须用值(例如0、null)初始化?
为避免编译器错误,为什么某些字符串(例如topStudent1)必须设置为null,而其他字符串(例如name1)则不必设置为null?为什么有些双精度(例如highScore)必须设置为0,而其他双精度(例如score1)必须设置为0,以避免编译器错误
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);
}
}
谢谢
# 1 楼答案
在访问所有变量之前,必须对其进行明确赋值(JLS §16),编译器会验证这一点:
由于
while
循环可能根本不执行(例如,用户输入1
),因此在printf
语句中使用4个变量(例如topStudent1
)需要在while循环之外初始化变量这样的初始化不必在声明行上,但在声明行上进行更简单
相比之下,其他变量(例如
name1
)不在while
循环之后使用,而仅在循环内部使用,并且在使用之前明确分配# 2 楼答案
有一个标准规则是
到目前为止,在使用之前,它必须通过
0
或some value
或null
对其进行初始化# 3 楼答案
这是因为您需要设置的是if和else块,编译器不确定它们是否将被初始化,因此为了停止错误,它会强制您初始化它们。不需要初始化的那些在if/else之外,因此它们将被声明。我希望这有帮助
为了澄清,编译器可以查看它们是否一定会通过您的逻辑进行初始化,如果只有可能发生,它将确保不会通过强制您声明来抛出null
# 4 楼答案
让我们以编译器的方式(当然是以高度简化的方式)来看看程序。我们首先看到的是变量声明,其中一些声明初始化了它们的变量
之后是
while
循环。一般规则是while
循环执行的次数未知,包括零次。因此,我们必须假设它是可能的它根本不会执行,这意味着在它中分配的任何变量可能根本不会被分配最后,我们有一个使用四个变量的输出语句:
topStudent1
、topStudent2
、highScore
和nextHighScore
。这些正是您发现需要初始化的。(实际上,它们只需要被分配到该语句之前的某个位置。)发生了什么事?由于编译器知道这四个变量中的每一个都需要一个值来支持
printf
,因此它需要保证这些变量已分配到某个地方。在while
循环内赋值不起作用,因为(据编译器所知)while
循环根本不会执行。如果在声明它们时没有对它们进行初始化,并且没有以编译器能够识别的方式分配它们(在声明它们和使用它们之间总是会发生),编译器会采取保守的观点,并决定它们可能未初始化# 5 楼答案
如果不在定义类成员的代码中直接指定值,则会为该类成员(静态和动态)指定默认值。但是,方法中的参数和变量不是指定的默认值,在使用之前需要设置为某个值(默认值或其他值)
# 6 楼答案
原因很简单,你需要保证你使用的一些值不会爆炸你的应用程序,因为它们没有初始化
怎么做
像这样:
执行此操作时:
然后使用变量并将其作为参数传递,但它们没有初始化,因此方法printf不知道编译时将打印什么,因此它们必须初始化为某个值(在这种情况下,也可以接受null)