我有以下Java代码:
import java.util.Scanner;
public class C2F_F2C {
public static void main(String[] args) {
boolean isNotValid = false;
double toConvert;
do {
System.out.print("What do you want to convert from Celsius to Fahrenheit? ");
Scanner in = new Scanner(System.in);
String toConvertString = in.nextLine();
isNotValid = false;
try {
toConvert = Double.parseDouble(toConvertString);
}
catch (java.lang.NumberFormatException e) {
System.out.println("Error: Not a number");
isNotValid = true;
}
} while (isNotValid);
double inCelsius = toCelsius(toConvert);
System.out.println("The value " + toConvert + " in Celsius is " + inCelsius);
}
public static double toCelsius( double fahrenheit ) {
double celsius = (fahrenheit -32)*(5/9);
return celsius;
}
}
但是,当我运行它时,会抛出以下错误:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The local variable toConvert may not have been initialized
The local variable toConvert may not have been initialized
at C2F_F2C.main(C2F_F2C.java:24)
我在do..while循环之前初始化变量,并在try..catch循环中设置值。看来该变量尚未设定。对不起,如果这是一个相当基本的问题,但我似乎无法弄明白。
答案 0 :(得分:2)
不,你不要在循环和try
之前初始化它。
这:
double toConvert;
是声明,而不是初始化。
这:
double toConvert = 0.0;
是初始化。
答案 1 :(得分:2)
您需要初始化local variables
。你认为你有initialized it inside the try block
,但是编译器不这么认为。如果 try块没有运行会怎么想?你有局部变量不是<强>初始化即可。你必须在声明过程中初始化它。
double toConvert=0.0d;
答案 2 :(得分:2)
我在do..while循环之前初始化了变量,
不,你没有初始化变量。你刚宣布它。默认情况下不会初始化局部变量。
并在try..catch循环中设置值
是的,确定你这样做了,但是想想当try-catch
中的初始化语句抛出异常时会发生什么?将处理异常,并且您的变量将不会被初始化。然后在你的程序中,当你试图访问变量时,你期望发生什么?
所以,只需给变量一个默认值。变化:
double toConvert;
到:
double toConvert = 0.0;
答案 3 :(得分:0)
tldr;当一个可以为变量分配一个初始值时,这样做是一个kludge而删除了有关程序流的有价值的信息。
相反,请考虑有问题的构造是什么。请注意,编译器知道循环体将至少执行一次,因为它使用do-while形式。以下是失败案例的简化示例:
int b;
try {
b = SomeMethodWhichMayOrMayNotThrowAnException();
} catch (Exception ex) {
// b not assigned
}
// What is the value of b here?
// The compiler answer is: It *may* (or *might*) not be initialized.
更正解决方案是在或中设置b
,否则稍后会阻止它在某种程度上使用编译器可以验证。
请记住,编译器不能使用编译时不知道的表达式来确定哪些分支可能会执行,也可能不会执行。因此,编译器不知道如果在那里捕获到异常将再次执行循环。
但是,请考虑将代码更改为:
double ReadValueToConvert (Scanner in) {
while (true) {
System.out.print("What do you want to convert from Celsius to Fahrenheit? ");
String toConvertString = in.nextLine();
try {
// No need to keep a flag for the loop
return Double.parseDouble(toConvertString);
}
catch (java.lang.NumberFormatException e) {
System.out.println("Error: Not a number");
}
}
// Compiler smart enough to know execution can never get here
}
// only create one Scanner, not one per loop
Scanner in = new Scanner(System.in);
// toConvert guaranteed to be assigned
double toConvert = ReadValueToConvert(in);
请注意它是如何绕过某些问题并简化代码的。