値と住所を伝える
2909 ワード
javaは伝値ですか?それとも住所ですか?この問題はもう長い間討論しました。一部の人は伝値と言っています。はたして伝値ですか?それとも住所ですか?私達はとりあえず住所をC++の伝達指針として理解します。
まず次のプログラムを見てください。
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に変えてみます。
私たちは上のSteringBufferを自分達の定義の対象に変えます。
私たちはもっとchange()の方法を修正します。
ハロー
私たちはchangeの方法でdを変えましたが、実際の対象demoは変わりませんでした。
このことから、javaの中のいわゆる「伝所在地」も実は一種の伝値である(あるいはjavaの中には跡地がない)。私たちが方法の「住所」を送る時は、実際には実際に参考になった住所のコピーです。これは私たちの参加者(ここでは彼らを一時的に指針として理解しています。)が指している住所と同じですが、彼らは違った実体です。したがって、私たちは方法において参照を再割り当てすると、変更されたのは参照先のアドレスだけであり、実際に参照されたアドレスは変更されていないので、その内容は変わらない。
まず次のプログラムを見てください。
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の中には跡地がない)。私たちが方法の「住所」を送る時は、実際には実際に参考になった住所のコピーです。これは私たちの参加者(ここでは彼らを一時的に指針として理解しています。)が指している住所と同じですが、彼らは違った実体です。したがって、私たちは方法において参照を再割り当てすると、変更されたのは参照先のアドレスだけであり、実際に参照されたアドレスは変更されていないので、その内容は変わらない。