1. ホーム

[解決済み】return型を持つJavaメソッドがreturnステートメントなしでコンパイルされる。

2022-04-05 02:20:52

質問

質問1:

次のコードは、なぜ return 文がなくてもコンパイルできるのでしょうか?

public int a() {
    while(true);
}

お知らせ whileの後にreturnを追加すると Unreachable Code Error .

質問2.

一方、次のようなコードはなぜコンパイルできるのでしょうか。

public int a() {
    while(0 == 0);
}

はそうでないにもかかわらず

public int a(int b) {
    while(b == b);
}

解決方法は?

<ブロッククオート

質問1:

次のコードは、なぜ return 文がなくてもコンパイルできるのでしょうか?

public int a() 
{
    while(true);
}

でカバーされています。 JLS§8.4.7 :

メソッドが戻り値の型を持つと宣言されている場合 (§8.4.5) 、メソッドの本体が正常に完了できる場合はコンパイル時エラーが発生します (§14.1) 。

言い換えれば、戻り値の型を持つメソッドは、値の戻り値を提供する return 文を使用してのみ戻らなければなりません。メソッドは、"その本体の終わりを落とすことは許されません"。メソッド本体の return 文に関する正確な規則については、§14.17 を参照してください。

メソッドが戻り値の型を持ちながら、戻り値のステートメントを含まないことも可能です。以下はその一例です。

class DizzyDean {
    int pitch() { throw new RuntimeException("90 mph?!"); }
}

コンパイラは、ループが決して終了しないことを知っているので ( true は常に真です)、この関数は普通に戻ることができない(本体の最後を落とす)ことも知っています。 return .

<ブロッククオート

質問2:

一方、次のようなコードはなぜコンパイルできるのでしょうか。

public int a() 
{
    while(0 == 0);
}

はそうでないにもかかわらず

public int a(int b)
{
    while(b == b);
}

での 0 == 0 の場合、コンパイラはループが決して終了しないことを知っています(その 0 == 0 は常に真となる)。しかし、それは はしない。 は、そのことを b == b .

なぜダメなのか?

コンパイラは 定数式 (§15.28) . 引用元 §15.2 - 表現の形式 (奇妙なことにこの文は§15.28にないので) :

式の中には、コンパイル時に決定できる値を持つものがあります。これらは 定数式 (§15.28).

あなたの中の b == b の例では、変数が関係しているため、定数式ではなく、コンパイル時に決定される仕様になっていません。 私たち は、この場合、常に真になることがわかります(ただし、もし bdouble として、QBrute ご指摘 で簡単に騙される。 Double.NaN である。 ではない == そのもの しかし、JLSは定数式がコンパイル時に決定されることを規定しているだけで、コンパイラが非定数式を評価しようとすることを許可していません。 bayou.io いいこと言うね ということです。もし、コンパイル時に変数を含む式を決定しようとする道を進み始めたら、どこで止めるのですか? b == b は明らかです(えー、非 NaN の値)はどうでしょうか? a + b == b + a ? または (a + b) * 2 == a * 2 + b * 2 ? 定数で線引きするのは理にかなっている。

つまり、式を決定しないので、コンパイラはループが決して終了しないことを知らないので、メソッドが普通に戻れると考えてしまうのです。 return . そのため return .