一个Java面试题,求解释原因

双人鱼XKQ 发布于 2016/07/14 13:29
阅读 1K+
收藏 4


public class Test {

public static void main(String args[]) {

StringBuffer a = new StringBuffer("A");

StringBuffer b = new StringBuffer("B");

Operator(a, b);

System.out.println(a + " " + b);

}


public static void Operator(StringBuffer x, StringBuffer y) {

x.append(y);

y = x;

}

}


public class Test {

public static void main(String args[]) {

StringBuffer a = new StringBuffer("A");

StringBuffer b = new StringBuffer("B");

Operator(a, b);

System.out.println(a + " " + b);

}


public static void Operator(StringBuffer x, StringBuffer y) {

x.append(y);

y = x;

}

}

最后输出: AB  B

加载中
2
沧海_Sea
沧海_Sea
传值 和 传引用 的区别
1
sucho
sucho

这个面试题主要是考察的是java方法传递引用的问题。

1.首先你在main方法中创建了两个StringBuffer对象,它们的引用分别指向的值是"A"和"B";

2.调用operator()方法时,因为你这里传递的是引用,会发生形参引用拷贝的过程!所以这里又新创建了两个对象,注意是又新创建了两个对象!但是这两个新创建的对象的引用也还是指向你在main方法中创建的两个StringBuffer对象.意思就是你形参中的x和main中的a这两个现在的指针地址是一样的,同理形参中y与main中的b这两个指针地址也是一样的.

3.在operator方法中,x.append(y);这个过程实际是改变x指针指向的值,注意是指向的值!值与指针是两个不同的概念!值和指针不能混淆!因为x指针指向的值发生了改变,所以main中的a的指针指向的值也发生了改变!对了,这里提一下,指针有内存地址,值也有内存地址,他们的内存地址是不一样的,你可以通过c语言的%p格式化输出;

4.operator方法中,y = x;这里步骤实际上是改变形参y的指针地址!但是并没有改变main中b的指针地址!因此此时形参的y打印输出的结果会是"AB",但是y的作用域只有在operator方法中.而main中b的指针地址仍然指向"B",所以格式化输出"B";

这道题主要是不好理解的地方在于形参它有自己的指针地址,只不过是和main中变量的指针地址一样而已.但是形参它自身更换了指针地址,并不代表main中的变量也会更换指针地址!

sucho
sucho
回复 @布道牛 : 1.请看下append方法的内部实现;2,你一般见过java除了=(等号)外改变引用的其它方法吗?(native除外); java正常情况下都是进行赋值运算,不像诸如C语言之类的玩指针玩内存......貌似java语言出现的初衷就是封装指针,指针这个一不小心玩坏了出现指针泄露排查问题可麻烦了......
布道牛
布道牛
@tuzhao 方法append 为啥是改变值,而 y=x 是改变指针地址
0
游弋丶
一看就知道没学过C语言,不知道指针
0
烟雨三月
烟雨三月
Operator(a, b); 传到 Operator 方法中的是 a 和 b 的地址的复制品,在 Operator 方法中 y = x; 修改的是 b 的地址复制品 y,并不会把 b 的地址设置成 a 的地址。 
0
东向利
东向利
在JAVA中除了基本数据类型(int,bool,String,long,char)之外,参数都是引用传址,也就是传的指针。所以所做的修改直接影响原值。
东向利
东向利
回复 @双人鱼XKQ : String不是基本数据类型,笔误。但是在参数负值时,和基本数据类型是一致的。
sweeeeeet
sweeeeeet
回复 @双人鱼XKQ : 并不是
双人鱼XKQ
双人鱼XKQ
String是基本数据类型吗?
0
SVD
SVD
public static void operator(StringBuffer x,StringBuffer y){
               // a 的拷贝变为了AB,a 的拷贝(x)和a 指向同一个内存地址,所以 a 变为了AB
              x.append(y); 
               //  y 指向了 a 的拷贝的地址,也就是 a 的地址,那么y 将不再影响 b 
              y=x;                
}



0
Ambitor
Ambitor
看看append 方法实现就知道了
0
飘逸的逸
飘逸的逸
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
//这两句话声明两个引用对象 a和b,在内存中分别指向"A","B"两个对象在内存中的地址

然后执行Operator(a, b);方法
进入方法之后,会创建两个新的对象x和y,因为a,b是引用类型,所以x和a指向同一个对象"A",y和b指向同一个对象"B"

x.append(y);
//这句话就是把x指向对象的值修改为"AB"(这样说是因为StringBuffer是可变的),修改后内存地址不变,所以x和a还是指向原来的对象,只是对应的值变成了"AB"
y=x;
//这句话会把此时x存储的内存地址赋值给y,此时y就和x就指向同一个对象,同理y就和a指向同一个对象.此时b中存储的内存地址一直没有变化.

所以输出结果是

a="AB", b="B"

public class TestStackHeap { public static void main(String[] args) { StringBuffer a = new StringBuffer("A"); StringBuffer b = new StringBuffer("B"); StringBuffer m = swap(a, b); System.out.println("main: a=" + a + ", b=" + b); System.out.println("a == m is " + (a == m)); } public static StringBuffer swap(StringBuffer x, StringBuffer y) { x.append(y); y = x; System.out.println("swap: x=" + x + ", y=" + y); return y; } } swap: x=AB, y=AB main: a=AB, b=B a == m is true ================================================================== public class TestStackHeap { public static void main(String[] args) { String a = new String("A"); String b = new String("B"); String m = swap(a, b); System.out.println("main: a=" + a + ", b=" + b); System.out.println("a == m is " + (a == m)); } public static String swap(String x, String y) { x = x + y; y = x; System.out.println("swap: x=" + x + ", y=" + y); return y; } } swap: x=AB, y=AB main: a=A, b=B a == m is false




0
cassia_
cassia_
我是不是眼花了。。。。。。上下两段看起来一样。。。。
返回顶部
顶部