0
public static Scanner getFileScanner()
{
    try{
        Scanner input = new Scanner(System.in);
        String file = input.nextLine();
        Scanner fs = new Scanner(new FileReader(file));            
    }catch (FileNotFoundException fe) {
        System.out.println("Invalid filename. Try another:");
        getFileScanner();
    }finally{
        return fs;
    }
}

変数fsが見つからないというエラーが表示され続けます。私の人生の理由がわかりません。

4

6 に答える 6

1

あなたfsはブロックの下で宣言されてtryいます...これを修正するには、ブロックの外で宣言します:-

Scanner fs = null;
try {
    ...
    fs = new Scanner(new FileReader(file));
}
catch (FileNotFoundException fe) {
    ...
}
finally {
    return fs;
}
于 2011-02-17T01:02:59.040 に答える
1

ブロック内で宣言された変数はtry、対応するブロック内のスコープにありませんfinally。一般的に、あなたのアプローチには多くの問題があります...たとえばreturn、ブロックの中に入るのは一般的に良い考えではありません。finally

これが私がすることです:

public static Scanner getFileScanner() {
  Scanner input = new Scanner(System.in);
  File file = null;
  while (true) {
    file = new File(input.nextLine());
    if (file.exists() && file.isFile())
      break;
    System.out.println("Invalid filename. Try another:");
  }
  return new Scanner(new FileReader(file));
}
于 2011-02-17T01:05:50.080 に答える
1

コード内の問題をリストすることから始めましょう:

  1. returnステートメントのコンパイルエラーはfs、他の回答で説明されているように範囲外であることが原因で発生します。

  2. に再帰呼び出しをgetFileScanner()行う場合、結果を割り当てたり返したりすることはありません。したがって、発信者には戻されません。

  3. ブロックでを使用することはreturn悪い考えです。その時点で伝播している可能性のある他の例外をすべて押しつぶします(破棄します)。たとえば、と一致しない例外、またはブロックでスローされた例外。finallycatchcatch

  4. input.nextLine()基になるストリームがEOFに達した場合、呼び出しは例外をスローします。たとえば、ユーザーが[CONTROL]+Dなどと入力しました。あなたはそれを捕まえる必要はありません(それはチェックされていません)が、finallyブロックのリターンはそれを(おそらく)押しつぶし、null代わりに発信者を取得します。うーん..。

  5. ハードワイヤリングにより、メソッドの再利用性が低下しますSystem.inSystem.out(OK、これはこの特定のケースで対処する必要のある問題ではない可能性があります。以下では対処しません...)

  6. StackOverflowError理論的には、あなたのメソッドは;をスローするように作成できます。たとえば、ユーザーが[ENTER]を何度も押した場合。この問題は再帰的ソリューションに固有のものであり、そのようにしないのは十分な理由です。

最後に、これらの問題に対処するメソッドのバージョンを次に示します。

public static Scanner getFileScanner() throws NoSuchElementException
{
    Scanner input = new Scanner(System.in);
    while (true) {
        String file = input.nextLine();
        try {
            return new Scanner(new FileReader(file));           
        } catch (FileNotFoundException fe) {
            System.out.println("Invalid filename. Try another:");
        }
    }
}

再帰を置き換え、を取り除き、finallyスローされる例外を宣言したことに注意してください。(その例外をキャッチして報告するか、アプリケーション固有の例外として再スローすることができます。)

于 2011-02-17T03:35:22.587 に答える
0

最初に宣言します。

public static Scanner getFileScanner() {
    Scanner input = new Scanner(System.in);
    Scanner fs = null;
    while(fs == null) {
        try{
            String file = input.nextLine();
            Scanner fs = new Scanner(new File(file));            
        }catch (FileNotFoundException fe) {
            System.out.println("Invalid filename. Try another:");
        }
    }
    return fs;
}
于 2011-02-17T01:01:37.120 に答える
0

tryブロックでfsを宣言し、別のスコープ(finallyブロック)でアクセスしようとしました。通常のパラダイムは、tryブロックの前にfsをnullとして宣言することです。

于 2011-02-17T01:03:00.487 に答える
0

他の人がコードサンプルで示したことを拡張するためだけに...

fsブロック内で変数を宣言するため、変数はキーワードtryの直後の中括弧内でのみスコープ(表示)されます。try

fs変数宣言をtryブロックからメソッド本体に移動することで、メソッド本体( 、およびブロック)getFileScanner内のすべてのブロックから変数にアクセスできるようになります。trycatchfinally

お役に立てば幸いです。

于 2011-02-17T01:14:37.637 に答える