传值还是传址?

zcwm 2003-01-14 06:55:46
传值还是传址
java对对象的传递是传址,对基本类型的传递是传值
有下面一个测试程序
public class Test{
public void ChangeString(String s){
s = s + " Changed";
}
public static void main(String args[]){
Test test = new Test();
String name = "name";
System.out.println("before :"+name);
test.ChangeString(name);
System.out.println("after :"+name);
}
}
按照对象传址理解,调用方法以后name应该发生变化,而实际上却没有,不知道谁能解释一下!
...全文
65 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
beyondhyb 2003-01-15
  • 打赏
  • 举报
回复
public class MyMainTest{
public int i;
public MyMainTest(){
i = 0;
}
public static void main(String args[]){
MyMainTest myTest = new MyMainTest();
myTest.addI(myTest);
System.out.println(myTest.i);
}
public void addI(MyMainTest argTest) {
argTest.i++;
}
}

请高手给我分析一下这段代码
bluesmile979 2003-01-15
  • 打赏
  • 举报
回复
同意大头,其实编程思想上有说的,String是个例外,我记得也只有它是例外。
tangjiyu 2003-01-15
  • 打赏
  • 举报
回复
我觉得把string 理解为一个特别特殊的类就行啦
taolei 2003-01-15
  • 打赏
  • 举报
回复
在java语言里是看不到对象地址的,甚至在JNI里也看不到对象地址。也就是说,在JNI里都无法直接操作java对象的数据。
事实上所有对象的操作都是通过对象的引用来完成的。
而java对象的引用和C++里面的引用是不一样的,C++里面的引用就是传地址。
从付值结果来看,java的引用和传值是一样的。用'='付值后的变量会指向一个新的对象(或null).

s = s + " Changed";
这行代码可以理解成(事实上编译器是这样解释的):
StringBuffer temp = new StringBuffer();
temp.append(s);
temp.append(" Changed");
s = temp.toString();

此时的s显然不是原来的s了,已经是对另外一个字符串对象的引用。


taolei 2003-01-15
  • 打赏
  • 举报
回复
正确说法应该是对象引用,而不是地址。
在纯java语言里看不到差别。
写过JNI的朋友可能会知道,多个对同一个对象的引用的值是不一样的。所以说这个引用值显然不是该对象的地址。

idilent 2003-01-14
  • 打赏
  • 举报
回复
class ObjectForTest{
public String TestString;
}

public class TestObjectChange{
public static void main(String arg[]){
ObjectForTest obTest = new ObjectForTest();
TestObjectChange Test = new TestObjectChange();
obTest.TestString = "Test";
System.out.println("The origal string is: " + obTest.TestString);
Test.ChangeObject(obTest);
System.out.println("The string is change by function: "+obTest.TestString);
obTest.TestString = "Test";
System.out.println("The origal string is: " + obTest.TestString);
ObjectForTest obTest2 = obTest;
obTest2.TestString = "Changed by another object";
System.out.println("The string is changed by another object " + obTest.TestString);
}
void ChangeObject(ObjectForTest ob){
ob.TestString = "changed by function";
}
}

这是我写的代码证明传地址
dreamhead 2003-01-14
  • 打赏
  • 举报
回复
这是因为String是一个immutable类。
s = s + " Changed ";
的结果是产生一个新的String,其值为原来s + " Changed "。
在函数里,s是发生改变了,其内存地址并不是原来的位置。
这个改变并没有影响到函数之外,所以,实际参数的内存地址仍然是原来的位置,所以你看到的结果是没有改变。

所谓immutable类是只要类的对象产生了,就不会改动,所以,即便其引用变了,其实际内存中的内容还是不会改变的。

可以参考一下,《Effective Java》关于immutable类的介绍或《Java与模式》中关于不变模式的讲解。
idilent 2003-01-14
  • 打赏
  • 举报
回复
我觉得可能是因为string是一个比较特殊的类的原因,现在我还没有安装好sdj,等安装好了后在讨论
yangjf 2003-01-14
  • 打赏
  • 举报
回复
s = s + " Changed ";
是机上的操作是创建了一个新的String对象然后让s指向它。
cqli2002 2003-01-14
  • 打赏
  • 举报
回复
当然是不变了
因为在传入方法ChangeString的是对象name在内存中的地址
但是当调用s = s + " Changed;后,方法内的s的内存中的地址已经改变了
和方法外的已经不同了,所以不管做了什么操作,都不会影响到对象name

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧