您的位置:首页 > 职场人生

一道面试题引发的争论和思考——Java到底是值传递还是引用传递

2019-01-03 14:19 288 查看

直接上题:

public class Example {
public static void main(String args[]) {
RandomTest ex = new RandomTest();
String str = new String("good");
char[] ch = { 'a', 'b', 'c' };
int a=1;
ex.change(str,ch,a);
System.out.println(str);
System.out.println(ch);
System.out.println(a);
}
public void change(String str1, char ch1[],int b) {
b=100;
str1 = "test ok";
ch1[0] = 'g';
System.out.println(str1);
}
}

打印语句的输出结果分别是什么?

test ok
good
gbc
1

changge()方法到底是值传递还是引用传递?
接下来从头开始分析:
1、main方法开始执行:
实例化一个Example 对象,ex为对象引用存放在栈内存中,new出来的对象,存放在堆内存中。
str,ch,a为局部变量,其中a为基本类型,直接存放在栈中,str为引用类型,引用存放在栈中, "good"存放在堆内存中

2、ex.change(str,ch,a);
change(String str1, char ch1[],int b),这一步的操作有:
将str的引用地址值0x02赋值给str,将ch的引用地址值0x03赋值给ch1,将a的值1,赋值给b

接下来进入change()方法中执行代码
b=100;
str1 = “test ok”;
ch1[0] = ‘g’;
对应内存中的操作为:

3、当change()方法执行完成后,str1, ch1, b 就会从栈中消失


4、main方法执行完之后,a变量,str,ch引用将从栈中消失,new Example(),将等待垃圾回收。

在Java中,变量分为以下两类:
①对于基本数据类型变量(int、long、double、float、byte、boolean、char),Java是传值的副本。
②对于一切对象型变量,Java都是传引用的副本。其实传引用副本的实质就是复制指向地址的指针,只不过Java不像C++中有显著的*和&符号。需要注意的是:String类型也是对象型变量,所以它必然是传引用副本。String类是final类型的,因此不可以继承和修改这个类。
不管Java参数的类型是什么,一律传递参数的副本。

根据Horstmann的《java核心技术》(中文第8版P115-P117)的描述,java中是没有引用传递的,原文摘录如下:
”java程序设计语言总是采用值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。“

”有些程序员(甚至是本书的作者),认为java程序设计语言对对象采用的是引用调用,实际上这种理解是不对的。”

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: