
メソッドの引数にオブジェクトを指定した場合、
それは「参照渡し」だと理解していました。
でも以下のプログラムでは、指定したオブジェクトに変化がありません。
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
-------------------------
どういうことでしょうか?
正しい知識をお教えください。
よろしくお願いします。

No.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
No.4
- 回答日時:
>指定したオブジェクトに変化がありません。
そもそも別のオブジェクトを参照しています。
このような場合は"フィールド変数"を使いましょう。
"フィールド変数"はひとつのクラス内で共通に使える変数です。
そして、メソッドの引数として宣言するのは
"局所変数"といいそのメソッド内でしか使えません。
つまり,"局所変数の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);
}
}
No.3
- 回答日時:
メソッドの仮引数に格納されるのは、あくまで実引数のコピー。
つまりそういう意味では「値渡し」です。
ここでは引数にオブジェクトすなわち参照型の値を受け渡しされているけれど、int型などのプリミティブな値を受け渡しする場合と機構的には同じだと考えればよいと思います。
No.2
- 回答日時:
一旦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の値も変わらない。
No.1
- 回答日時:
元のオブジェクトを書き換えてませんよね?
bがBigDecimal(1)を指していたところに、別途BigDecimal(2)のオブジェクトを作って、bがそっちを指すようにしただけ。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ピクチャーボックスに点を打つ...
-
GridViewに行追加するには?
-
サーブレットコンテキストの意...
-
servletからjspへオブジェクト...
-
Vba ListViewの行挿入に関して...
-
VB2005でADDとINSERTの違いは?
-
VBAでの[]
-
VBスクリプトでテキストファイ...
-
String型からlong型への変換は...
-
「タイプ初期化子が例外をスロ...
-
エクセルVBAで、条件に一致する...
-
中学のクラス数
-
0歳児の指しゃぶりに関して
-
スーパークラスからサブクラス...
-
変数名の付け方
-
標準モジュールとクラスモジュ...
-
関数内の変数に<summary>コメン...
-
僕の出身中学校は200人同級生が...
-
引数で日付を2つ与え、その間の...
-
UMLのクラス図はmain()も含むん...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Dispose()は、どんな時に使うの...
-
VB.NETでのnothing の意義について
-
サーブレットコンテキストの意...
-
エクセルVBA 画像を貼り付ける...
-
Excel VBA 定数にオブジェクト...
-
VB.netでメソッドからコントロ...
-
servletからjspへオブジェクト...
-
ピクチャーボックスに点を打つ...
-
C#で親にイベントを投げる方法
-
VB6.0にて、ワールド変換(ピク...
-
VBAでの[]
-
C#のクラスで値渡しをする
-
JSPでのArrayListの表示につい...
-
Vba ListViewの行挿入に関して...
-
String型からlong型への変換は...
-
Javaでブラウザ判定
-
[ASP.NET]DropDownListのDB連携...
-
getHeigth,getWidthについて
-
Objectクラスのオブジェクトを...
-
エクセルVBA/SpecialCellsで特...
おすすめ情報