关于java中的参数传递

问题的引入是因为下午在群里看到了一个网友的问题:

给定如下Java 代码,编译运行后,输出结果是( )。
public class Test {
public static void main(String [ ] args) {
StringBuffer a = new StringBuffer(“A”);
StringBuffer b = new StringBuffer(“B”);
operate(a , b);
System.out.println(a + ”,” + b);
}
static void operate(StringBuffer x , StringBuffer y) {
x.append(y);
y = x;
}
}
A. A,B B. AB,B C. A,AB D.AB,AB

朋友可以猜猜这个答案,我也想告诉大家,答案是:B。也许有人会很惊讶,也许有人会很淡定。因为StringBuffer是一个类,对于类的使用,通过new,在堆中创建一个类的实例,利用一个引用来实现对这个对象的操作。当把一个引用当作参数传递到一个函数中的时候,C++采取的是:这个参数是一个地址。而在java中没有地址这个概念,一切都是值传递,那么这里又是怎么控制的。

首先,我做了一个测试:

public class Text {

public static void main(String[] args) {

String s = "b";

f(s);

System.out.println(s);

}

static void f(String s) {

s = "c";

}

} /* output

b

*///~

从结果可以看出:形参的效果并没有作用到实参中。我们继续看下一段代码:

public class Text {

String s = "b";

public static void main(String[] args) {

Text t = new text();

f(t.s);

System.out.println(t.s);

}

static void f(String s) {

s = "c";

}

} /* output

b

*///~

这里的输出结果还是为b。继续:

public class Text {

String s = "b";

public static void main(String[] args) {

Txet t = new Text();

f(t);

System.out.println(t.s);

}

static void f(Text t) {

t.s = "c";

}

} /* output

c

*///~

从结果中可以看出:形参的效果作用到了实参,这里的引用发生了效果。

String为系统带的类,而Text为自定义的类,为了防止是自定义类跟系统类的影响,又使用了另外一个系统类List进行验证:

public class Text {

public static void main(String[] args) {

List<Integer> list = new ArrayList<Integer>();
list.add(33);
l(list);
System.out.println(list);

}

static void l(List<Integer> list) {
list.add(55);
}

} /* output

[33, 55]

*///~

从输出结果中可以看出:类的引用效果得以发挥。

针对上面的结果,我想朋友们会有一些意外,因为在java基础语言学习中,我们曾经对“==”与“equals()”的操作曾经进行了很多的讨论,结果说明:String类是一个引用类型,给出一段代码,以供大家学习:

public class SimpleTypeText {

public static void main(String[] args) {
String s1 = "a";
String s2 = "a";
String s3 = new String("b");
String s4 = new String("b");
System.out.println("s1 == s2 ? " + (s1 == s2) );
System.out.println("s1.equals(s2) ? " + s1.equals(s2));

System.out.println("s2 == s3 ? " + (s2 == s3) );
System.out.println("s2.equals(s3) ? " + s2.equals(s3));

System.out.println("s3 == s4 ? " + (s3 == s4) );
System.out.println("s3.equals(s4) ? " + s3.equals(s4));

(s4, s1);
}
static void f(String s) {
s = "a";
}
static void g(String s, String s1) {
s = "a";
System.out.println("通过常字符串:" + s == s1);
s = new String(s1);
System.out.println("通过new方法:" + s == s1);
}
} /*output:

s1 == s2 ? true
s1.equals(s2) ? true
s2 == s3 ? false
s3.equals(s3) ? true
s3 == s4 ? false
s3.equals(s4) ? true
通过常字符串:true
通过new方法:false

*///~

总结:

1. thinking in java 中对String类型对象有这样一段描述:

String对象是不可变的,没一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象。

对String类型的对象做参数有这样的一段描述:
每当把String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。

2. 在字符串的声明中,利用常字符串初始化的时候,系统会从已有的常字符串进行查找,如果存在此字符串常量,则不再生成新的字符串常量,但是new方法不是这样的,即它不进行查找,直接开辟一段新的空间,存储这个字符串。

声明:以上代码均为参考,希望对基础有些帮助。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yanmushi/archive/2010/05/09/5573022.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值