7

JLS によると、インスタンス変数初期化子または名前付きクラスのインスタンス初期化子がチェック済み例外クラスをスローできる場合、その例外クラスまたはそのスーパークラスの 1 つが各コンストラクターの throws 句で明示的に宣言されていない限り、コンパイル時エラーです。そのクラスであり、そのクラスには少なくとも 1 つの明示的に宣言されたコンストラクターがあります。

だから私はこれを行う場合 -

class A{
 {
  throw new FileNotFoundException();
 }
public A() throws IOException{
    // TODO Auto-generated constructor stub
}
}

これにより、コンパイル時に「初期化子は正常に完了する必要があります」というエラーが発生します

その間

class A{
 {
  File f=new File("a");
  FileOutputStream fo=new FileOutputStream(f);
  fo.write(3);
 }
public A() throws IOException{
    // TODO Auto-generated constructor stub
}
}

このコードは、コンパイル時エラーを示していません。コンストラクターで throws 句を宣言したにもかかわらず、前のコードがコンパイルされないのはなぜですか?

4

3 に答える 3

4

イニシャライザが例外なく実際に完了することができる場合、いくつかの条件が必要です。

あなたの場合、それが起こる方法はありません。

試す:

if(/*condition-to-fail*/) {
    /*Not always, only when something is wrong. Compiler knows that.*/
    throw new FileNotFoundException(); 
}

アップデート:

次のステートメントは、実際に例外をスローしています。

throw new FileNotFoundException(); 

したがって、無条件でプログラムの実行は常にそこで終了します。

次の間 -

FileOutputStream fo = new FileOutputStream(f);

コンストラクターFileOutputStream(File)は常にその例外をスローするとは限りません。

throws 句はpublic FileOutputStream(File file) throws FileNotFoundException、その例外をスローする可能性があることを示しているだけであり、実行時にファイルが見つからない場合にのみスローします。

于 2013-02-23T15:38:26.553 に答える
2

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.6

インスタンス初期化子が正常に完了できない場合は、コンパイル時エラーです。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

スイッチブロックではない空でないブロックは、その中の最後のステートメントが正常に完了できる場合に限り、正常に完了することができます。

..。

ifステートメントは、else部分があるかどうかに関係なく、通常とは異なる方法で処理されます。このため、このセクションの最後で個別に説明します。

..。

ifステートメントを「条件付きコンパイル」の目的で便利に使用できるようにするために、実際のルールは異なります。

..。

于 2013-02-23T16:16:00.273 に答える
1

最初のケースでは、コンパイラは、明示的にスローしたため、インスタンス初期化子が正常に完了しないことをすでに認識していますFileNotFoundException。コンパイラのスマートコード評価と言えます。ただし、インスタンス初期化子が正常に完了する可能性がわずかでもあるとコンパイラーに信じ込ませれば、コンパイラーはコンパイル中に文句を言うことはありません。たとえば、以下のコードでは、ファイルIDonotexist.txtは私のディレクトリに存在せず、スローされると確信していますFileNotFoundExceptionが、それでもコンパイラは正常にコンパイルできます。なんで?ファイルの存在は、コンパイル中ではなく、コードの実行中にチェックされるためです。

class A
{
    {
        FileReader fr = new FileReader(new File("IDonotexist.txt"));
    }
    public A() throws IOException
    {
        // TODO Auto-generated constructor stub
    }
    public static void main(String st[])throws Exception
    {
        A a = new A();
    }
}

これは、最終的な変数の初期化の場合と似ています。たとえば、次のコードでは、コンパイラはコンパイル時エラーを表示します

public void calling()
    {
        final int i;
        int k = 90;
        if ( k == 90)
        {
            i = 56;
        }
        System.out.println(i);//Compiler will show error here as: variable i might not have been initialized
    }

if ( k == 90)しかし、条件を次のように置き換えるとif(true)、コンパイラはエラーを表示しません。コンパイラは、それiが確実に何らかの値を割り当てられることを知っているからです。

于 2013-02-23T16:20:16.403 に答える