アプリ版:「スタンプのみでお礼する」機能のリリースについて

メソッドの引数にオブジェクトを指定した場合、
それは「参照渡し」だと理解していました。
でも以下のプログラムでは、指定したオブジェクトに変化がありません。
public static void main(String[] args) {

BigDecimal b = new BigDecimal(1);

System.out.println(b);

test(b);

System.out.println(b);
}

public static void test(BigDecimal b) {
b = new BigDecimal(2);
}
出力は以下です。
-------------------------
1
1
-------------------------
どういうことでしょうか?
正しい知識をお教えください。
よろしくお願いします。

A 回答 (5件)

public static void test(BigDecimal b) {


b = new BigDecimal(2);
}
この部分でnewされていますので、bの参照先があたらしいオブジェクトを参照するようにかわるはずですよね。そう考えてしまうのはわかります。

変数名がmain関数内と同じなので説明がしづらいので、下記のように変更させてください。

public static void main(String[] args) {

BigDecimal mainb = new BigDecimal(1);

System.out.println(mainb);

test(mainb);

System.out.println(mainb);
}

public static void test(BigDecimal testb) {
testb = new BigDecimal(2);
}

ここでtestbとmainbは同じアドレスであると思ってしまうと、勘違いしてしまいます。あくまでtestbとmainbはおなじアドレスを「参照している」のであり、同じアドレスではありません。
局所的に説明すると下記のような感じです。

-------------
mainb : 5454363
-------------
testb : 5454363
-------------
5454363 : 1
-------------

それをもって、
test関数内でtestbに新しいnew BigDecimalをおこなっても、
testbのアドレス参照先がかわるだけで、mainbにはなんの変更も行われません。

この説明でわからない場合は参考URLを読んでみてください。

参考URL:http://www.tec-q.com/note/2007/04/_java_13.html
    • good
    • 0

>指定したオブジェクトに変化がありません。


そもそも別のオブジェクトを参照しています。

このような場合は"フィールド変数"を使いましょう。
"フィールド変数"はひとつのクラス内で共通に使える変数です。

そして、メソッドの引数として宣言するのは
"局所変数"といいそのメソッド内でしか使えません。

つまり,"局所変数のb"と"フィールド変数のb"は別物となります

public class Test{
//フィールド変数
private static BigDecimal b;
public static void main(String[] args){
b=new BigDecimal(1);
System.out.println(b);
test(b);
System.out.println(b);
}
//メソッドの引数bは局所変数
//当メソッドの外では使えない
public static void test(BigDecimal b){
//なのでTestクラスのフィールド変数bを参照
Test.b=new BigDecimal(2);
}
}
    • good
    • 0

メソッドの仮引数に格納されるのは、あくまで実引数のコピー。


つまりそういう意味では「値渡し」です。

ここでは引数にオブジェクトすなわち参照型の値を受け渡しされているけれど、int型などのプリミティブな値を受け渡しする場合と機構的には同じだと考えればよいと思います。
    • good
    • 0

一旦Javaは忘れてC言語へ。


間違っていたら指摘よろしくお願いします>識者様

int main(){
int i = 5;
func(i);
printf("%d",i); //5
}

void func(int a){
// mainのiとaは同じ値が違う領域に入っている。== 値渡し

a = 3;
}

===========================

int main(){

int * x; // int *型。実際には無いと思うけど,JavaのGenerics使ってpointer<T> で Tがintになっているって説明した方が解る?
x = (int *)malloc(sizeof(int));
//メモリの領域にint型の大きさの部分が確保され,そのアドレスが返る。
//実際には確保しようとしたらメモリ不足だった、ということもあるが,その処理は書かない。

*x = 10; //アドレスの指す先の領域(int型)に値を代入。

func(x);

printf("%d",i); //20

free(x); //確保した領域を解放。

}

void func(int * a){

*a = 20;

}

全く同じ。mainのxとaも同じ値(int *のアドレス)が違う領域に入っている。
アドレスが指す領域(int型)は同じ。 int *型の値渡し == int 型の参照渡し
*aに20を突っ込んだから20が表示された。

*aではなくaに別の値を突っ込んだ場合,
aは変わるが,*aの内容は変わらない。→xは元の値を保ったまま。*xの値も変わらない。
    • good
    • 0

元のオブジェクトを書き換えてませんよね?



bがBigDecimal(1)を指していたところに、別途BigDecimal(2)のオブジェクトを作って、bがそっちを指すようにしただけ。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!