まず、コードの一部を見てみましょう
public class Text16 {
public static void main(String[] args) {
Circle demo = new Circle(5);
System.out.println(demo.radius);
change(demo);
System.out.println(demo.radius);
Circle a = new Circle(1);
Circle b = new Circle(2);
method(a,b);
System.out.println("一、a半径:"+a.radius+",b半径:"+b.radius);
}
public static void method(Circle x,Circle y){
Circle tmp = x;
x = y;
y = tmp;
}
public static void change(Circle x)
{
x.radius=0;
}
}
class Circle{
double radius;
Circle(double x){
radius = x;
}
}
結果:
これを見るのは少し大変です
値によって渡される8つの基本的なタイプのオブジェクトを除いて、他のオブジェクトは参照によって渡されるとよく言われるためです。
そして、この例では、
change(Circle x)
このメソッドは元のオブジェクトの値を変更しますが、これは単に参照を渡すだけではありませんか?
しかし、私たちが呼び出すとき、この推論によると
public static void method(Circle x,Circle y)
2つのオブジェクトの値を交換する必要があるが、交換しない場合、これはなぜですか?
この問題の根本的な原因は、Javaで渡されるパラメーターの誤解です。
オブジェクトの8つの基本的なタイプは値によって渡され、他のオブジェクトは参照によって渡されます
実際にはそうではありません。
基本的な型のオブジェクトやJavaの他のオブジェクトがすべて値で渡されても、
ここで、「値」は単に「アドレス指定するメモリ内のプリミティブ型またはオブジェクト」として理解できます(正確ではありません)。
呼び出し
change(Circle x)
しかし、それは実装されていません
x.radius=0;
以前は、記憶はこんな感じでした
x.radius=0;
その後、記憶はこんな感じ
このように分析できます。デモを呼び出した後、アドレスがxに割り当てられ、2つが同じメモリ空間を指し、半径の値がxだけ変化すると、デモの値は自然に変化します。
同様に、通話を分析します
public static void method(Circle x,Circle y){
しかし、コードを実行する前に
メモリアドレスはこんな感じです
次に実行します
Circle tmp = x;
x = y;
y = tmp;
後のメモリマップ
xとyのアドレスは交換されますが、aとbのアドレスは影響を受けないため、aとbが指すオブジェクトは自然に変更されません。
理解できたら、別の例を見てみましょう
Class User{
private String name;
.
.
.
}
public static void foo(User user){
user.setName("Max");// AAA
user = new User("Fifi");// BBB
user.setName("Rowlf");// CCC
}
public static void main(String[] args){
User basicUser = new User("Rover");
foo(basicUser );
}
すみません、「AAA」、「BBB」、「CCC」の3行のコードが実行された後のオブジェクトbasicUserの名前は何ですか?
'AAA'行:名前は 'Max';
'BBB'行:名前は 'Max';
'CCC'行:名前は 'Max';
自分で分析する
メモリスペースのヒープとスタックがわからない場合は、ビデオによる説明をお勧めします。
http://study.163.com/course/courseMain.htm?courseId=343001
30レッスンと31レッスン