11502


質問が連投になって大変申し訳ないのですが。  
javaを学習中でありますが、引数の引渡し作用がいまいちわかりません。

[code]

    class CallByValue{
    public static void main(String args[]){
        int i   = 5;
        int j[] = { 1, 2, 3, 4};
        StringBuffer sb = new StringBuffer("abcde");
    
        display(i, j, sb);
    
        a(i, j, sb);
    
        display(i, j, sb);
    }
    
    static void a(int i, int j[], StringBuffer sb) {
        i = 7;
        j[0] = 11;
        sb.append("fghij");
    }
    static void display(int i, int j[], StringBuffer sb) {
        System.out.println(i);
        for(int index = 0; index < j.length; index++)
            System.out.println(j[index] + " ");
        System.out.println("");
        System.out.println(sb);
    }}
    
[/code]

このコードで出されるメッセージは  
5  
1  
2  
3  
4

abcde  
5  
11  
2  
3  
4

abcdefghij  
です。  
main()で記述されている diplay()で一度表示して a()でstatic void a()の値を戻して変えて次の
display()に表示といった順にメッセージを表示していると考えているのですが

[code]

    static void a(int i, int j[], StringBuffer sb) {
        i = 7;
        j[0] = 11;
        sb.append("fghij");
    }
    
[/code]

このコードをみると 7 11 2 3 4 fghijとなるのではないかと思います。

i = 7と書いているのにどうして i=5のままで出されるのでしょうか  
またsb.append("fghij")と書かれているのにどうして abcdefghijと出されるのでしょうか。  
よろしくお願い致します。


CC BY-SA 3.0
2015-06-19T04:57:17.150
11501
2015-06-19T09:55:06.100
10197
question
java
javaの引数の引渡し作用についてよくわかりません


Java の関数は値渡しになります。関数を呼び出す側から変数が渡されているのではなく値が渡されています。

[code]

    public class Foo {
        public static void foo() {
            int i = 0; // (1) i に 0 という値が格納される
            bar(i);    // (2) i の値が bar の引数として渡される
        }
        public static void bar(int n) {
            n = 1;     // (3) 値が渡されているだけなので変数の中身を更新しても意味が無い
        }
    }
    
[/code]

違う変数名を使うとイメージ湧きやすいと思います。  
ただし値渡しとはいっても渡される物が何かによって初心者の方が躓く結果が現れます。  
Java の Object を継承したインスタンスも同様に値が渡されます。

[code]

    class Boo {
        int n = 0;
        public void setValue(int n) { this.n = n; }
        public int getValue() { return this.n; }
    }
    
    public class Foo {
        public static void foo() {
            Boo b = new Boo(); // (1) b に Boo のインスタンスが格納される
            b.setValue(0);     // (2) 中身の値を更新する
            bar(b);            // (3) インスタンスという値が渡される
        }
        public static void bar(Bar b) {
            b.setValue(1);     // (4) b が変更されるのではなく
                               //     b から辿る事が出来る n が更新される。
            b = new Boo();     // (5) 変数を上書きしても (4) は壊れない。
        }
    }
    
[/code]

関数 foo が生成した b を引数経由で関数 bar に渡して更新し、関数 foo に戻す事は出来ませんが、b の中身を更新する事は出来ます。  
これはインスタンスだけでなく、例えば配列を渡して配列を丸ごと書き換えて戻す事は出来ないけれど、配列の中身を変えて戻すことは出来る、という意味と同じです。

上記の例だと i の値を変えても意味は無いですが、a から辿れる StringBuffer の中身を自身で更新する事は出来るのです。


CC BY-SA 3.0
2015-06-19T05:14:49.540
11502
2015-06-19T05:14:49.540
440
11501
answer


javaで扱うデータ型の種類としては大きく「値型」と「参照型」の２種類があって、  
例えばint のような数値を表すような基本的なタイプはその値をそのまま保持しているので「値型」と呼びます。  
対して、クラス(フィールドやらクラスの情報やらなんやら)や配列(型の情報、それぞれの要素の値、長さなどを持つ)のような複雑な値を持つものは、そのままを保持という形にすると扱いが煩雑なので、  
代表→｛実際の内容、フィールドやらメソッドやらの部分｝  
のように｛…｝の本体部分を参照するものを持って扱うようにします。  
こういうタイプのモノを参照型と呼びます。  
（もちろん「代表」→ {int}の様にint 型を表現するとか全てのタイプを参照型にすることはできるでしょうがメモリを余分に消費します）

今、関数の呼び出しで値型の変数と参照型の変数を渡したとすると、  
値型の場合は「値」そのものがコピーして渡されます。  
参照型の場合は、「代表」がコピーされて渡されます。  
関数側では、  
値がコピーされたモノを扱っても、それはコピーですからオリジナルには影響ありません。  
「代表」が渡された場合「代表」それ自体はコピーですが、指している参照先である本体部分は同じですから  
「代表」を使って本体部分を操作するので、元の内容が変更されます。  
「代表」自体はコピーなので値型と同じくこれ自体がもし変更できるとしてもオリジナルの「代表」を変更することはできませんが、指している中身自体は同じなのでメソッド呼び出しなどの操作で中身の変更ができます。

必ずしも正確な説明では無いかも知れないですが、そんな感じです。

* * *

`int j[] = { 1, 2, 3, 4};`  
は、int 型の要素１，２，３，４を持つ配列に`j`と名前を付けるということです。  
先の説明で言う、`j`が「代表」ということになります。  
ｊ→｛[１，２，３，４], length, ...}  
そこで、  
`j[0] = 11;`  
は、ｊが指す本体の０番目の要素を１１に更新するという意味です。  
ｊを使って本体の内容を変更していることになります。  
それで、この操作後は  
ｊ→｛[１１，２，３，４], length, ...}  
になります。（０番目の要素１は１１で置き換えられた）

`j[]={0,9,8,7}`  
このような書き方は初期化の時(変数名を定義する時に)のみできる（と考えて下さい）  
[ ]は、変数名と数値を伴って  
`変数名[数値]`の様に書いて、  
「変数の保持している「数値」番目の要素１つ」を意味するので、  
それに対して{数値, 数値, 数値...}のような複数の値を指定しようとするのは意味が合いません。  
（他の言語では１つの数値でなく範囲を指定できるようなものがあります）  
また、`arraycopy`(配列のコピー)とか`fill`のような複数の要素を対象とするようなメソッドがあります。


CC BY-SA 3.0
2015-06-19T08:48:05.030
11512
2015-06-19T09:55:06.100
2015-06-19T09:55:06.100
5044
5044
11501
answer