运行以下代码打印输出结果会是什么?
public static void main(String[] args) {
int a = 10;
int[] b = {1,2,3};
String c = "中";
setA(a);
setB(b);
setC(c);
System.out.println(a);
System.out.println(b[1]);
System.out.println(c);
}
public static void setA(int a) {
a=100;
}
public static void setB(int[] b) {
b[1]=200;
}
public static void setC(String c) {
c="国";
}
答案是:10 200 中 。为什么修改变量a和变量c的值又变回去?
setA方法在执行之前,main方法将a=10压入栈。当setA方法运行时将a=100压入栈。而当setA方法执行完毕,a=100被弹栈。其实就是setA压入栈的a超出作用域,所以打印输出a=10。
seB方法执行前b已经静态初始化,b变量在栈内存中,b的数组对象在堆内存中。setB方法得到的是b对象的地址值。b[1]=200也是直接修改了堆内存的对象值。所以setB方法结束后b[1]也是被修改了。
String是引用类型,按照上面理论应该也会被修改,但是并没有被修改。
其实String在作为实参传值给setC时,并不是传的String的地址值,而是String内容。
//可以运行以下代码可知,String是传值,而非传址。
public static void main(String[] args) {
String c = "中";
System.out.println(c.getBytes());
}
public static void setC(String c) {
System.out.println(c.getBytes());
}
既然传的不是地址值,在setC方法自然无法修改(字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享)。