Java基础面试——传值问题

来源:互联网 发布:linux 休眠 编辑:程序博客网 时间:2024/06/11 04:33

以下程序输出什么内容:
public class Test1 {

public void test1(){    StringBuilder sb1 = new StringBuilder("a");    StringBuilder sb2 = new StringBuilder("b");    int a = 1;    test2(a, sb1, sb2);    System.out.println(“a=”+a);    System.out.println(“sb1=”+sb1);}public void test2(int a,StringBuilder sb1,StringBuilder sb2){    a = 100;    sb1.append("b");    sb1 = sb2;}public static void main(String[] args) {    Test1 t = new Test1();    t.test1();}

}
输出:a=1
sb1=ab
根据结果可以知道a并没有改变,sb1只是通过append改变了内容,对于sb1=sb2并不会对“真正的”sb1进行操作,所以没有发生改变。
那么,这是为什么呢?

首先,看看这三句话:对于Java传值,

  • 1.对象传引用;
  • 2.基本数据类型传值;
  • 3.String虽然是引用数据类型,由于创建后不能修改,可以认为是传值。

接着,具体解释这几句话:

  • 1.将一个对象作为参数传到一个函数中,其实是将这个对象的内存地址传过去了,即形参指向该内存地址,对于题中的sb1以下会解释。
  • 2.将一个基本数据类型传到一个函数中,其实是将这个基本数据类型的值的一个副本穿过去了,所以修改副本的值并不会对本来的实参有影响,这个比较好理解,题中的a就不解释了。

最后,对那道题进行解释:
一张图就可以很清楚的搞定
这里写图片描述

一开始,实参sb1、sb2各自指向堆中的内存地址(黑线),将sb1,sb2作为形参传入test2()函数后,在栈中的形参各自指向对应的内存地址(蓝线)
当执行

  • sb1.append(“b”);

由于现在sb1(形参)仍然指向堆中的“a”,所以会变成“ab”;
但是当执行

  • sb1 = sb2;

sb1(形参)就改变了指向的内存地址,变成了指向堆中的“b”(红线),但是注意,

  • System.out.println(“sb1=”+sb1);

这句话是输出sb1(实参),而现在sb1(实参)指向的堆中的内容,现在是“ab”,所以,最后输出结果是ab。