public class Test {
public static void main(String[] args) {
int a =0;
String b ="b";
StringBuilder c =new StringBuilder("c");
test(a,b,c);
System.out.println("a = " + a +",b = " + b +",c = " + c);
}
public static void test(int a, String b, StringBuilder c) {
a = a +1;
b = b +"1";
c = c.append(1);
}
}
这是遇到的面试题。当时我的回答是a = 1,b = b1,c = c1。
so,当然这个是错的。回来run了一下程序,答案是a = 1,b = b,c = c1。
然后和同学讨论了一下,加上百度,发现要理解这个答案,并不容易。这里仅仅了解按值传递这个概念是不够的,这里设计到的java基础知识还包括对象引用和对象的关系,形参和实参的关系。
String b = "b"中,String b创建了一个对象引用,"b"则是创建了一个对象(在内存中开辟了一块区域),= 号则讲对象引用指向了这个对象,换个说法就是对象引用保存了对象的内存地址。(这里只是简单介绍了对象引用和对象的关系)
调用一个函数,实参传递值给形参时,基本数据类型是直接拷贝一个新的值,引用类型则是拷贝一个内存地址,所以实参和形参指向的是同一个对象。String和StringBuilder都是引用类型,但是在test里对他们的操作其实是有区别的。
//这里是重点
b = b + "1",由于String具有不可变现,这个操作相当于创建了一个新的对象,所以这里形参是指向了一个新的对象。而c = c.append(1)并没有创建新的对象,还是对原有对象进行操作。
public class hello{
public static void main(String[] args){
int a = 0;
String b = "b";
StringBuilder c = new StringBuilder("c");
int a1 = a;
a1 = a1 +1;
String b1 = b;
b1 = b + "1";
StringBuilder c1 = c;
c1.append(1);
// test(a,b,c);
System.out.println("a = "+a+" b = "+b+" c = "+c);
}
或者把test里的方法放到外边写,效果也是一样的。b1 = b+"1",b1这个对象引用指向了新的对象。
网友评论