Java値の受け渡しと参照の受け渡しに関する一般的な誤解

まず、コードの一部を見てみましょう


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){
   
   

しかし、コードを実行する前に

メモリアドレスはこんな感じです



aはアドレスをxに渡しますbはアドレスをyaに渡しますxは同じオブジェクトを指しますbと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レッスン




おすすめ

転載: blog.csdn.net/a447332241/article/details/78939962