面试的的多了,多多少少会有些面试官会问到Java的值传递问题, 或者在笔试题中也会出现, 那么Java的参数传递是怎样的呢?
1. 如果参数类型是原始类型(基本类型),那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.
2. 如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址对应的那个对象中的值,那么在函数内的改变会影响到传入的参数。
如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。
@Test public void test1() { String str = new String("good"); char[] ch = {'a', 'b', 'c'}; change(str, ch); System.out.println(str); // good System.out.println(ch); //gbc } public void change(String str, char[] ch) { str = "test OK!"; ch[0] = 'g'; }
@Test public void test2() { StringBuffer a = new StringBuffer("A"); StringBuffer b = new StringBuffer("B"); operate(a, b); System.out.println(a + "," + b); //AB,B } private void operate(StringBuffer a, StringBuffer b) { a.append(b); b = a; }
@Test public void test3() { Integer x = new Integer(1); System.out.println(x); //1 t(x); System.out.println(x); //1 } private void t(Integer x) { x = new Integer(2); }
综上所述, 基本数据类型传递的是值得拷贝;对象类型传递的是引用的拷贝(地址的传递),而String类型传递的虽然也是对象,但它不同于一般的对象类型, 它String类被设计为不可修改的类型(final修饰)也就是对String对象的任何修改都将重新创建一个对象而放弃以前的内存空间的引用.
那么StringBuffer 和 Stringbuilder 呢?
重点理解为什么,function_1和function_2结果不同?
下面是function_1的图解:
builder.append("4")之后
下面是function_2的图解:
builder = new StringBuilder("ipad"); 之后
说明StringBuffer和StringBudder也是地址的传递.