进来看看,你也会很疑惑的。

guodong66 2009-10-28 09:45:44
class Test2 {
String a = "1";
String b = "2";
}
public class NoUpdate {
public static void changeUpd(Test2 t) {
t.a = "abc";
t.b = "123";
}
public static void main(String[] args) {
Test2 t2 = new Test2();
changeUpd(t2);
System.out.println(t2.a + "----" + t2.b);
}
}

这个程序输出 abc----123 ;
但是如果修改一下,
publicclass Test1 {

publicstaticvoid changeStr(String str){
str="welcome";
}
public static void main(String[] args) {

String str="1234";
changeStr(str);
System.out.println(str);
}
}
这里就输出 1234
同样传递的是对象,为什么第二个程序的值没有被修改呢?两个程序传递的参数都应该是原对象的引用的,为什么?想不明白,呵呵
...全文
175 点赞 收藏 32
写回复
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
qjcslgnhwayagain 2009-10-28
很复杂的问题,先收藏
回复
gukuitian 2009-10-28
我忘了在什么地方看到过这样一句话,除了string,其它对像都是地址传递。
回复
guodong66 2009-10-28
[Quote=引用 9 楼 cangyingzhijia 的回复:]
java属于值传递,而非引用传递
[/Quote]

你太有才了。
回复
苍蝇1号 2009-10-28
java属于值传递,而非引用传递
回复
helix616 2009-10-28
[Quote=引用 3 楼 chdw 的回复:]
那是因为对于第一个对象来说changeUpd并没有改变参数Test2 t2的指向,
也就是changeUpd中的t2与main始终为同一内存地址。


但是第二个,改变的是参数String str的指向,也就是change方法中str已经和main中的str指向不同内存地址
所以不会影响main中的t2



[/Quote]
觉得有道理的。栈会为changeStr函数的形参分配地址,这个形参与实参会指向同一个内存地址。
第一个方法,实际上通过形参改变了t2对象中成员的指向,所以打印时候自然也看到了这个变化。
第二个方法,实际上形参的指向改变了,但是实参的指向并没有改变,所以打印无变化
回复
java1109 2009-10-28
值传递的问题
回复
guodong66 2009-10-28
干了这么久程序员,书页没少看,发现这东西还没搞明白,超级郁闷啊。。。。
回复
岁月之梦 2009-10-28
这个string很烦的!
回复
guodong66 2009-10-28
加断点跟踪看了,发现String类型做参数传递的时候不是传递的引用,但String分明是一个对象....
回复
ChDw 2009-10-28
那是因为对于第一个对象来说changeUpd并没有改变参数Test2 t2的指向,
也就是changeUpd中的t2与main始终为同一内存地址。


但是第二个,改变的是参数String str的指向,也就是change方法中str已经和main中的str指向不同内存地址
所以不会影响main中的t2



回复
JavaAlpha 2009-10-28
它的具体的内部实现,可以加个断点跟踪看看具体的内容的变化。
回复
xgj1000 2009-10-28
String是比较特殊的一个对象。把它当参数传递等同于基本数据类型。
回复
李子做IT 2009-10-28
不错,mark
回复
heroboy0923 2009-10-28
[Quote=引用 30 楼 guodong66 的回复:]
引用 27 楼 awusoft 的回复:
改一下,也许你就比较好理解了
Java code

publicclass Test1 {

    publicstaticvoid changeStr(String abc){
        abc="welcome";
    }publicstaticvoid main(String[] args) {

        String str="1234";
        changeStr(str);
        System.out.println(str);
    }
}

是两个不同的变量,你改变了变量的指向,但并不是改变变量所指向的对象.

String a = "12";
a="45";//改变了a的指向,并没有改变"12"这个对象的任何东西,本来a指向"12"这个对象,然后你不想要这个对象了,让a指向"45"这个对象


ok明白了,

类比于, String str = "abc";
str +="bcd";
实际上就是new了一个新对象,在让str指向新对象,也是StringBuffer出现的原因。呵呵。
[/Quote]

正解,不过单线程的话推荐StringBuilder,StringBuffer是线程安全的,效率低
回复
guodong66 2009-10-28
[Quote=引用 27 楼 awusoft 的回复:]
改一下,也许你就比较好理解了
Java code

publicclass Test1 {

publicstaticvoid changeStr(String abc){
abc="welcome";
}publicstaticvoid main(String[] args) {

String str="1234";
changeStr(str);
System.out.println(str);
}
}

是两个不同的变量,你改变了变量的指向,但并不是改变变量所指向的对象.

String a = "12";
a="45";//改变了a的指向,并没有改变"12"这个对象的任何东西,本来a指向"12"这个对象,然后你不想要这个对象了,让a指向"45"这个对象
[/Quote]

ok明白了,

类比于, String str = "abc";
str +="bcd";
实际上就是new了一个新对象,在让str指向新对象,也是StringBuffer出现的原因。呵呵。
回复
big_bigtree 2009-10-28
值传递的问题
如果你希望传进去的String被修改的话
将参数修改为String[] 即可
回复
zlllyk110 2009-10-28
String 和 八种基本类型传值调用
回复
awusoft 2009-10-28
改一下,也许你就比较好理解了


publicclass Test1 {

publicstaticvoid changeStr(String abc){
abc="welcome";
}
public static void main(String[] args) {

String str="1234";
changeStr(str);
System.out.println(str);
}
}


是两个不同的变量,你改变了变量的指向,但并不是改变变量所指向的对象.

String a = "12";
a="45";//改变了a的指向,并没有改变"12"这个对象的任何东西,本来a指向"12"这个对象,然后你不想要这个对象了,让a指向"45"这个对象
回复
guodong66 2009-10-28
[Quote=引用 23 楼 heroboy0923 的回复:]
public final class String
    implements java.io.Serializable, Comparable <String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

*********************************************
这是jad反编译的String类的源代码,其底层实现是一个final char[] value,因为是final的,无法改变其内容,每次赋值的时候都是重新分配内存(其实更复杂,还要考虑常量池的问题,你就理解为重新分配好了)
[/Quote]

呵呵,不能就理解为什么样了,已经工作2年多了,一直这么混过来的,需要清楚下了。去翻源代码修改者看了。
回复
heroboy0923 2009-10-28
按照你的例子,如果把String a和String b都声明为final的话,代码就错了
回复
发动态
发帖子
Java SE
创建于2007-09-28

6.1w+

社区成员

Java 2 Standard Edition
申请成为版主
社区公告
暂无公告