値と住所を伝える

2909 ワード

javaは伝値ですか?それとも住所ですか?この問題はもう長い間討論しました。一部の人は伝値と言っています。はたして伝値ですか?それとも住所ですか?私達はとりあえず住所をC++の伝達指針として理解します。
まず次のプログラムを見てください。
 
package luojing;

public class StringDemo

{

	public static void main(String[]args)

	{

		String str=new String("hello");

		//      str  

		change(str);

		System.out.println(str);

		

	}

	

	public static void change(String str1)

	{

		str1+="luojing";

	}

}
プログラム実行結果:ハロー
 
      strの値は変化していないことが見られます。Stringタイプは対象ですが、通常量ですので、転送のアドレスは定数ポインタconst int*p=aに相当します。pの指向を変えることはできますが、*P(a)の内容を変えることはできません。javaでは、文字列定数strの値を変更したときに、実際には新しくStringオブジェクトを作成して、新しいオブジェクトのアドレスをstr 1に割り当てます。だから、私たちはstr 1が指すアドレスを変更しただけです。そして、私たちはchange()パラメータにアドレスを伝える時に、伝達するのはstrアドレスのコピーです。つまり、伝達するのは新しいstrがアドレスを指すポインタstr 1です。しかし、change()関数が変更されたのは、私たちが伝達するポインタstr 1だけです。本当のstrアドレスには影響がありません。だから、私達がstrを出力する時、その値はまだhelloです。
自分でまとめます。String文字列は一度に与えられた値を変えることができないので、もし変えたら、実は新しいオブジェクトを作ったのです。
上のプログラムのSteringをSteringBufferに変えてみます。
 
public class StringDemo

{

	public static void main(String[]args)

	{

		StringBuffer str=new StringBuffer("hello");

		//      str  

		change(str);

		System.out.println(str);

		

	}

	

	public static void change(StringBuffer str1)

	{

		str1.append("luojing");

	}

}

プログラム実行結果:hello luojing      この時はstrの内容が変わります。
 
私たちは上のSteringBufferを自分達の定義の対象に変えます。
 
public class test

{

	public static void main(String[] args) 

	{

		Demo demo=new Demo("hello");

		//      demo.name  

		change(demo);

		System.out.println(demo.getName());

	

	}

	

	public static void change(Demo d)

	{

		d.setName("luojing");

	}



}



class Demo

{

	private String name;

	

	public Demo(String s)

	{

		name=s;

	}

	public String getName()

	{

		return name;

	}

	public void setName(String str)

	{

		name=str;

	}

}
プログラム実行結果:luojing 私たちがStringBufferを使うのと同じ効果です。
 
私たちはもっとchange()の方法を修正します。
package luojing;

public class test 

{

	public static void main(String[] args) 

	{

		Demo demo=new Demo("hello");

		//      demo.name  

		change(demo);

		System.out.println(demo.getName());

	

	}

	

	public static void change(Demo d)

	{

		Demo d1=new Demo("hello java");

		d=d1;	

	}



}



class Demo

{

	private String name;

	

	public Demo(String s)

	{

		name=s;

	}

	public String getName()

	{

		return name;

	}

	public void setName(String str)

	{

		name=str;

	}

}

運転結果:
ハロー
     私たちはchangeの方法でdを変えましたが、実際の対象demoは変わりませんでした。
 
     このことから、javaの中のいわゆる「伝所在地」も実は一種の伝値である(あるいはjavaの中には跡地がない)。私たちが方法の「住所」を送る時は、実際には実際に参考になった住所のコピーです。これは私たちの参加者(ここでは彼らを一時的に指針として理解しています。)が指している住所と同じですが、彼らは違った実体です。したがって、私たちは方法において参照を再割り当てすると、変更されたのは参照先のアドレスだけであり、実際に参照されたアドレスは変更されていないので、その内容は変わらない。