文章目录
- 前言
- 一、 Java到底是值传递还是引用传递
- 1.1 Java基本数据类型和引用类型
- 1.2 数据传递方式
- 二、结论
- 三、参考资料
前言
之前在搞清楚了Java引用类型的关系,过了没多久,在看原型模式的时候又看到了Java引用的相关信息,突然发现要想起来还有点费劲,好记性不如烂笔头,记下来!
之前会去了解引用类型是在学习引用类型(强引用,软引用,弱引用和虚引用,想了解看参考资料)的时候看到了如标题的问题,就去了解了。
一、 Java到底是值传递还是引用传递
1.1 Java基本数据类型和引用类型
- 基本类型:编程语言中内置的最小粒度的数据类型。它包括4大类8种数据类型:
4种整数类型:byte、short、int、long
2种浮点数类型:float、double
1种字符类型:char
1种布尔类型:boolean - 引用类型:引用也叫句柄。引用类型,是编程语言中定义的在句柄中存放实际内容所在地址的一种数据形式。它主要包括:
- 类
- 接口
- 数组
- 还有个比较特殊的是String\Boolean\Integer等特殊包装类,比如String API种有句话
their values cannot be changed after they are created意思是他们在创建后因为没有修改自身的方法,每次修改或者拼接都是新建对象。
这些特殊包装类存储于堆内存,理论上属于引用数据类型,但又由于每次都是新建对象,传递的都是对象的值,所以传递上,String等特殊包装类属于值传递。
【新增】
关于这里,几个月后我有了新的理解,为什么说是值传递,是他被当成了值传递。
虽然String等特殊包装类是对象,是引用传递,但是由于机制原因,特殊包装类由final修饰,对象内容不支持修改,而在方法传递这件事上,Java的引用传递是可以修改地址指向堆对象的内容,而不能修改指向!!!,所以String等特殊包装类可以当成值传递。
1.2 数据传递方式
- 值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
- 共享变量传递:是指在调用函数时将实际参数的地址复制一份传递到函数中(可以理解为把指针.tosString()了一下给了方法),那么在函数中对参数所进行的修改,将影响到实际参数。
- 引用传递:形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。
当数据类型为基础数据类型时,因为值存放在局部变量表中,无论如何修改只会修改当前栈帧的值,这个值是外部变量的副本,所以不能修改原始变量。
当是特殊包装类像Integer和Boolean,如图,在进行传递时,因为Java自动装箱机制,传递的是值。(图来自参考资料2)
当传递的参数是引用类型时,Java会将这个引用类型的地址复制一份,传递到方法内。如果被修改了就是修改了堆内存里的对象,原对象会发生改变。
二、结论
无论是值传递还是引用传递,其实都是一种求值策略。在求值策略中,还有一种叫做按共享传递(call by sharing)。其实Java中的参数传递严格意义上说应该是按共享传递。
按共享传递,是指在调用函数时,传递给函数的是实参的地址的拷贝(如果实参在栈中,则直接拷贝该值)。
按共享传递可以说是一种特殊的值传递,传递的这个值,就是该对象地址的拷贝。
严格来说,应该说Java中的传递是共享传递,或者说是值传递。
三、参考资料