1. ホーム
  2. java

[解決済み] 非voidメソッドにreturnステートメントがない場合のコンパイル

2022-02-15 02:21:59

質問

という場面に遭遇しました。 非ボイドメソッド が欠落しています。 戻り ステートメントを使用しても、コードはコンパイルされます。 whileループの後のステートメントが 到達不能 (デッドコード)で、決して実行されることはないでしょう。しかし、なぜコンパイラは何かを返すことについて警告さえしないのでしょうか?あるいは、なぜ言語が無限ループを持つ非voidメソッドを許し、何も返さないのでしょうか?

public int doNotReturnAnything() {
    while(true) {
        //do something
    }
    //no return statement
}

whileループの中にbreak文(条件付きでも)を入れると、コンパイラは悪名高いエラーを訴えます。 Method does not return a value をEclipseで、そして Not all code paths return a value をVisual Studioで実行します。

public int doNotReturnAnything() {
    while(true) {
        if(mustReturn) break;
        //do something
    }
    //no return statement
}

これは、JavaとC#の両方に言えることです。

解決方法は?

<ブロッククオート

なぜ言語が無限ループを持つ非voidメソッドを許し、何も返さないのでしょうか?

非ボイドメソッドのルールは を返すすべてのコードパスは、値を返さなければならない そして、このルールはあなたのプログラムでも満たされており、0個のコードパスのうち0個が値を返します。 このルールは、quot;すべての非ボイドメソッドは返すコードパスを持たなければならない"ではありません。

これによって、次のようなスタブメソッドを書くことができる。

IEnumerator IEnumerable.GetEnumerator() 
{ 
    throw new NotImplementedException(); 
}

これは非voidメソッドです。それは があります。 はインターフェイスを満たすために非voidメソッドでなければなりません。しかし、何も返さないからと言って、この実装を違法とするのは馬鹿げているように思えます。

あなたのメソッドが到達不可能な終点を持つのは goto (ただし while(true) は、より快適な書き方である。 goto )の代わりに throw (の別の形式です)。 goto は関係ありません。

なぜコンパイラは、何かを返すことについて警告すらしないのでしょうか?

なぜなら、コンパイラは、そのコードが間違っているという良い証拠を持たないからです。ある人がこう書きました。 while(true) で、それをやった人は自分が何をしているかを知っていた可能性が高いと思われます。

<ブロッククオート

C#の到達性解析について詳しく知りたいのですが、どこで読むことができますか?

このテーマに関する私の記事は、こちらをご覧ください。

ATBG:デファクトとデジュールの到達可能性

そして、C#の仕様書を読むことも検討してみてください。