CodeGym/Java Blog/ランダム/Javaの戻りキーワード
John Squirrels
レベル 41
San Francisco

Javaの戻りキーワード

ランダム グループに公開済み
人のメンバー
ご存知のとおり、Java 言語はオブジェクト指向プログラミング言語です。つまり、すべてのものは物である、というのが基本的な考え方、つまり基礎中の基礎です。オブジェクトはクラスを使用して記述されます。クラスは、状態と動作を定義します。たとえば、銀行口座には、口座内の金額という形で状態があり、口座残高を増減させる動作がある場合があります。Java では、動作はメソッドを通じて実装されます。メソッドの定義方法の学習は、Java の学習の最初に行われます。たとえば、Oracle の公式チュートリアルでは、「メソッドの定義」という見出しの下にあります。ここで注意すべき重要な点が 2 つあります。
  • 各メソッドには署名があります。シグネチャは、メソッドの名前とその入力パラメータで構成されます。
  • メソッドには戻り値の型を指定する必要があります。メソッドの戻り値の型は、メソッド宣言で宣言します。
戻り値の型はメソッド シグネチャの一部ではありません。繰り返しますが、これは、Java が厳密に型指定された言語であり、コンパイラーは、どの型がどこで使用されているかを事前に可能な限り把握したいという事実の結果です。繰り返しますが、これは私たちを間違いから守るためです。基本的に、それはすべて正当な理由のためです。そして、これが私たちにデータを扱う文化を再び植え付けたように思えます。そのため、メソッドには戻り値の型が指定されます。Java のreturnキーワードは、実際に返すために使用されます。 Java 戻りキーワード - 1

Java で return は何をするのか

returnキーワードは、Oracle チュートリアル(こちら)で説明されているように制御フロー ステートメントです。公式チュートリアルの「メソッドから値を返す」セクションで値を返す方法について読むこともできます。コンパイラは、メソッドの戻り値がメソッドの指定された戻り値の型と一致することを確認できるかどうかを注意深く追跡します。Tutorialspoint のオンライン IDE を使用して例を考えてみましょう。原始的な例を見てみましょう。
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
ご覧のとおり、プログラムのエントリ ポイントであるmainメソッドがここで実行されます。コード行は上から下に実行されます。mainメソッドは値を返すことができません。そこで値を返そうとすると、「エラー: Main メソッドは void 型の値を返さなければなりません」というエラーが発生します。したがって、この方法は単に画面に出力するだけです。次に、文字列リテラルをメッセージを生成する別のメソッドに移動しましょう。
public class HelloWorld {

    public static void main(String[] args) {
        System.out.println(getHelloMessage());
    }

    public static String getHelloMessage() {
        return "Hello World";
    }

}
ご覧のとおり、returnキーワードを使用して戻り値を示し、それをprintlnメソッドに渡しました。getHelloMessageメソッドの宣言は、メソッドがStringを返すことを示します。これにより、コンパイラはメソッドのアクションが宣言方法と一致しているかどうかをチェックできます。当然のことながら、メソッド宣言で指定された戻り値の型は、コードで実際に返される値の型よりも広くなる可能性があります。つまり、重要なことは、型変換が可能であるということです。そうしないと、コンパイル時にエラー「エラー: 互換性のない型」が発生します。ところで、おそらく次のような質問があるでしょう。なぜreturnなのかということです。制御フローステートメントとみなされますか? それはプログラムの通常のトップダウンの流れを混乱させる可能性があるからです。例:
public class HelloWorld {

    public static void main(String[] args) {
        if (args.length == 0) {
            return;
        }
        for (String arg : args) {
            System.out.println(arg);
        }
    }

}
例からわかるように、 Java プログラムのmainメソッドが引数なしで呼び出された場合は、それを中断します。returnステートメントの後にコードがある場合、そのコードにはアクセスできないことに注意してください。当社のスマート コンパイラはこれを認識し、そのようなプログラムの実行を防ぎます。たとえば、次のコードはコンパイルできません。
public static void main(String[] args) {
        System.out.println("1");
        return;
// we use output method after return statement, which is incorrect
        System.out.println("2");
 }
これを回避するための汚いハックが 1 つあります。たとえば、デバッグ目的やその他の理由です。上記のコードは、returnステートメントをifブロックでラップすることで修正できます。
if (2==2) {
    return;
}

エラー処理時の return ステートメント

他にも非常にトリッキーな点があります。エラー処理と組み合わせてreturnを使用できます。すぐに言いたいのは、catchブロックでreturnステートメントを使用するのは非常に悪い形式であるため、使用は避けるべきであるということです。しかし、例が必要ですよね? ここにあります:
public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Value: " + getIntValue());
    }

    public static int getIntValue() {
        int value = 1;
        try {
            System.out.println("Something terrible happens");
            throw new Exception();
        } catch (Exception e) {
            System.out.println("Cached value: " + value);
            return value;
        } finally {
            value++;
            System.out.println("New value: " + value);
        }
    }

}
一見すると、finally は常に実行されるため、2 を返す必要があるように見えます。しかし、いいえ、戻り値は 1 になり、 finallyブロック内の変数への変更は無視されます。さらに、valueにオブジェクトが含まれており、finallyブロックでvalue = nullと指定するとします。その後、null ではないそのオブジェクトがcatchブロックで返されます。ただし、returnステートメントは、 finallyブロック内で正しく機能します。明らかに、同僚は return ステートメントに関するちょっとした驚きに対して感謝しないでしょう。

void.class

そして最後に。void.classという奇妙な構造体を書くことができます。ふーむ。なぜ、そしてそれは何を意味するのでしょうか?Java Reflection APIに関連するさまざまなフレームワークや難しいケースでは、これが非常に役立ちます。たとえば、メソッドがどの型を返すかを確認できます。
import java.lang.reflect.Method;

public class HelloWorld {

    public void getVoidValue() {
    }

    public static void main(String[] args) {
        for (Method method : HelloWorld.class.getDeclaredMethods()) {
            System.out.println(method.getReturnType() == void.class);
        }
    }
}
これは、メソッド内の実際のコードを置き換える必要があるテスト フレームワークで役立ちます。ただし、これを行うには、メソッドがどのように動作するか (つまり、メソッドがどのような型を返すか) を理解する必要があります。上記のコードで mainメソッドを実装する 2 番目の方法もあります。
public static void main(String[] args) {
        for (Method method : HelloWorld.class.getDeclaredMethods()) {
            System.out.println(method.getReturnType() == Void.TYPE);
        }
 }
2 つの違いについては、Stack Overflow で非常に興味深い議論を読むことができます。「java.lang.Void と void の違いは何ですか?」
コメント
  • 人気
  • 新規
  • 古い
コメントを残すには、サインインしている必要があります
このページにはまだコメントがありません