-1

我有以下 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 循环中设置了值。似乎尚未设置变量。抱歉,如果这是一个相当基本的问题,但我似乎无法弄清楚。

4

4 回答 4

2

不,您不会在循环和try.

这 :

double toConvert;

是声明,而不是初始化。

这 :

double toConvert = 0.0;

是一个初始化。

于 2013-02-09T20:00:32.530 回答
2

您需要初始化local variables. 你认为你有initialized it inside the try block,但编译器不这么认为。它认为如果try 块没有运行怎么办?您有未初始化的局部变量。您必须在声明本身期间对其进行初始化。

double toConvert=0.0d;
于 2013-02-09T20:01:09.350 回答
2

我在 do..while 循环之前初始化了变量,

不,您没有初始化变量。你刚刚宣布了。默认情况下不初始化局部变量。

并在 try..catch 循环中设置值

是的,你确实这样做了,但是想想当你的初始化语句try-catch抛出异常时会发生什么?将处理异常,并且您的变量不会被初始化。然后在您的程序中,当您尝试访问该变量时,您期望会发生什么?

所以,只需给变量一个默认值。改变:

double toConvert;

到:

double toConvert = 0.0;
于 2013-02-09T20:02:12.937 回答
0

tldr; 虽然可以为变量分配初始值,但这样做是一种杂乱无章的做法,会删除有关程序流程的有价值信息

相反,请考虑有问题的构造是什么。请注意,编译器知道循环体将至少执行一次,因为它使用 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.

一个更正确的解决方案是在 catchb 内设置以其他方式阻止它稍后以编译器可以验证的方式使用。

请记住,编译器不能使用在编译时不知道的表达式来确定哪些分支可以执行或不可以执行。因此,编译器不知道如果在那里捕获到异常,循环将再次执行。

但是,请考虑将代码更改为以下内容:

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);

请注意它如何绕过一些问题并简化代码。

于 2013-02-09T20:16:58.457 回答