-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 形式を使用しているため、コンパイラはループ本体が少なくとも 1 回実行されることを認識していることに注意してください。失敗したケースの簡単な例を次に示します。

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

いくつかの問題を回避し、コードを簡素化する方法に注意してください。

于 2013-02-09T20:16:58.457 に答える