

<http://www.javadrive.jp/start/method/index5.html> このサイトを参考にしています。

この中にある、

[code]

    class JSample5_1{
      public static void main(String args[]){
        int kekka;
    
        kekka = bai(9);
        System.out.println(kekka);
    
        kekka = bai(5);
        System.out.println(kekka);
      }
    
      private static int bai(int n){
        return n * 2;
      }
    }
    
[/code]

の部分なんですが、よく理解できておりません。`return n*2` が `bai(int n)` の `n` の部分に`x2`
が入るので、`(bai=x2)` ということで合ってますか？

そして `kekka=bai(9)` に `x2` が入って `18`,  
`kekka=bai(5)` に `x2` が入って `10` ということですか？

あと、最初のほうに `void`（戻り値を無効にするという意味ですか？）と書いてありますが  
`return` を書くと、`return` が適用され、最初の `void` は打ち消されるということですか？


CC BY-SA 3.0
2015-02-16T09:50:56.733
6571
2015-02-17T05:51:40.123
2015-02-16T09:55:07.453
8269
question
java
戻り値を使ってメソッドを返す方法について


一般的なプログラミング言語では、特に細工を入れない限りは演算(`+` とか `-` とか `*` とか `/` 等)は即時で評価されます。`bai(9)`
を実行すると n には 9 という`値`が格納されるので `n * 2` は`即時で評価`され 18 という数値の結果が出ます。その値は return
で呼び出し元(main)に戻され kekka という変数に代入されます。掛け算という物が代入されるのではなく、結果である 18 である事に注意して下さい。  
n には `x2` といった様な`倍数`の様な物が格納されている訳ではありません。

以下の例を見て下さい。

[code]

    int n = 3;
    kekka = bai(n); // 3 を渡す
    n = 4; // kekka には既に 6 が代入されているので n を変更しても意味はない
    
[/code]

kekka に 6 が格納された後で n の値を変えても遅いのです。

もう一つ例を示します。

[code]

    kekka = bai(2 * 3);
    
[/code]

これは以下の様に動作します。

  1. `2 * 3` が評価され 6 という値が作られる
  2. 6 という値が bai に渡される
  3. bai により、`2 * 6` つまり 12 という値が戻される
  4. kekka という変数に 12 が格納される

今後プログラミングをやっていく過程で`遅延評価`という言葉と共に、即時で評価しない仕組みが登場してくるかと思いますが、今回のケースは当てはまりません。ご注意下さい。

**おまけ**

[code]

    interface Calclator {
        int calc(int lhs, int rhs);
    }
    
    class OpPlus implements Calclator {
        public int calc(int lhs, int rhs) {
            return lhs + rhs;
        }
    }
    
    class OpMinus implements Calclator {
        public int calc(int lhs, int rhs) {
            return lhs - rhs;
        }
    }
    
    class OpMult implements Calclator {
        public int calc(int lhs, int rhs) {
            return lhs * rhs;
        }
    }
    
    class OpDiv implements Calclator {
        public int calc(int lhs, int rhs) {
            return lhs / rhs;
        }
    }
    
    public class JSample5_1 {
        private static Calclator getCalculator(char op) throws RuntimeException {
            switch (op) {
                case '+':
                    return new OpPlus();
                case '-':
                    return new OpMinus();
                case '*':
                    return new OpMult();
                case '/':
                    return new OpDiv();
                default:
                    throw new RuntimeException("Invalid operator");
            }
        }
    
        public static void main(String[] args) {
            // 足し算クラスを戻り値として貰う
            Calclator c = getCalculator('+');
    
            // c には足し算クラスが入っているので calc を実行すると 1 + 2 が
            // 実行され、結果 3 が返る。
            System.out.println(c.calc(1, 2));
        }
    }
    
[/code]

上のソースを実行し、main の `'+'`
の部分を他の演算子に変えて試して貰うと本来の`戻り値を使ってメソッドを返す方法`をどう実装するかが理解できると思います。  
関数オブジェクトという、関数本体を返す方法は Java8 で実現出来るのですが、おそらく勉強段階の今はやらない方がよいと思います。


CC BY-SA 3.0
2015-02-16T10:12:43.493
6574
2015-02-17T05:51:40.123
2015-02-17T05:51:40.123
440
440
6571
answer


まずは `Java` 言語についての入門書などを一度読むのをお勧めしますが、、、

提示されたソースには1つのクラスと、そのクラスの2つのメソッドが含まれています。

[code]

    // クラス JSample5_1 宣言の開始
    class JSample5_1{
    
      // main メソッドの開始
      public static void main(String args[]){
        int kekka;
    
        kekka = bai(9);
        System.out.println(kekka);
    
        kekka = bai(5);
        System.out.println(kekka);
      }
    
      // bai メソッドの開始
      private static int bai(int n){
        return n * 2;
      }
    }
    
[/code]

それぞれのメソッドの定義は以下のような意味があります。

[code]

      // 静的(static)な public メソッド
      // 返値: なし(void)
      // 引数:   String 型の配列
      public static void main(String args[]){
        // ...
      }
    
      // 静的(static)な private メソッド
      // 返値: int型
      // 引数:   int型 `n`という名前でアクセスできる
      private static int bai(int n){
        // ...
      }
    
[/code]

> あと、最初のほうに void（戻り値を無効にするという意味ですか？）と書いてありますが  
>  return を書くと、return が適用され、最初の void は打ち消されるということですか？

返値が `void` なのは、`main` メソッドのみです。そのため、`main` メソッド内では値を返して(`return`) いません。

対して `bai` メソッドでは、`int` 型を返しています。

`bai` メソッドの動作については理解されているようですが、`bai(5)` のようにメソッドを呼び出すと、`bai` メソッド内では `n`
という名前で渡された引数にアクセス出来るようにメソッドが定義されています。  
そのため、`bai(5)` を呼び出すと、`5 * 2` が計算された結果 `10` が呼び出し元に返り(`return`)ます。


CC BY-SA 3.0
2015-02-16T10:13:40.573
6575
2015-02-16T10:13:40.573
2944
6571
answer


`ｎ`の部分には、渡された数値が入ります。  
`bai(9)` の場合は`ｎ`に`９`が入り  
`bai(5)` の場合は`ｎ`に`５`が入ります。  
結果として`n*2`を返すので、  
`bai(9)`は、`9*2`に置き換えられ  
`bai(5)`は、`5*2`に置き換えらると考えることができます。  
つまり実質上  
`kekka = bai(9);`は`kekka = 9*2;`と同じで  
`kekka = bai(5);`は`kekka = 5*2;`と同じとみなすことができます。

返値指定の`void` は、「戻り値を無効にするという意味」や「voidを返す」というよりは「戻り値がない」という意味です。  
void の指定が有効なのはこの場合mainメソッドだけで、baiでの戻り値指定はintなのでreturnを書くと指定が打ち消されるわけではありません。  
`return void;` //void がそもそもエラー  
`return 0;` //値を返せないのに返そうとするのでエラー,`return ;`はＯＫ  
とかmainメソッドのブロックに書くとコンパイルがエラーになるはずです。


CC BY-SA 3.0
2015-02-16T10:26:41.607
6577
2015-02-16T10:37:11.113
2015-02-16T10:37:11.113
5044
5044
6571
answer