关于java中只有值传递的思考
java中只有值传递?很多时候面试会碰到这个类型的题目,这是个老生常谈的问题,但很多人会栽在上面,根本原因是对基础原理把握不够清晰。先看一个题目:
1.下面这段代码中打印a是多少?
int a = 1;//1
func(a);//2
System.out.println("a: " + a);//4
public static void func(int t){
t = 5;//3
}
控制台打印显示a为1,相信大多数人是不会错的。再看下面这个题目:
2.下面这段代码中打印str是多少?
String str = "hi";//1
func_noEffect(str);//2
System.out.println("str: " + str);//4
public static void func_noEffect(String str){
str = "jiay";//3
}
控制台打印显示str为hi,这时候答对的就不会是大多数了。很多开发做了几年的都会栽在这里,有人就会问String类型是引用类型怎会会打印hi呢,这就是知其然而不知其所以然。
java基本数据类型
java中基本数据类型包括内置类型即值类型、引用类型、常量,这个问题涉及的值类型和引用类型。一般程序员都知道值类型存储在栈上,引用类型存储在堆上,下面用张图描述一下它们的存储结构。
图中a是int值类型,数值1存储在栈上,str是String引用类型,实例对象hi存储在堆上。注意String类型有一个引用变量是存储在栈上的,引用变量中存储的是实例对象hi的地址。
java方法传参
基本类型是值传递,引用类型是引用传递。按字面意思理解是没有问题的。
值传递方法中传入的是值类型的副本,问题1中值传递解释:
- 1.定义变量a值为1。
- 2.调用函数func传入形参a的副本值1。
- 3.修改形参的值为5。
- 4.打印实参到控制台。这个过程中并没有更改实参的值。
图解:
引用传递方法中传入的是引用变量的副本,问题2中引用传递解释: - 1.定义引用变量str指向对象实例hi。
- 2.调用函数func_noEffect传入形参引用变量str的副本。
- 3.形参(引用变量str的副本)指向String类型实例jiay。
- 4.打印实参到控制台。这个过程中并没有更改实参对象。
图解:
由上可知方法传参都是值类型的,因此从函数传参角度讲java中都是值传递。
java中的引用传递
先看一段代码:
StringBuilder stringBuilder = new StringBuilder("hi");
func_effect(stringBuilder);
System.out.println("sb: " + stringBuilder);
public static void func_effect(StringBuilder sb){
sb.append(",jiay");
}
这段代码打印出来sb:hi,jiay。有人会问这里怎么跟上面问题2不一样的,难到不应该是sb:hi吗,呵呵···。
图解:
实参与形参指向的是同一个对象,所以函数调用完,控制台中打印实参的实例内容变成了hi,jiay。对比问题2这里大家应该注意到了String貌似跟其它的引用类型变量不太一样,String类型=(赋值)时指向一个新实例。
现在再看文章标题就是另一番感受了,还是那就话,程序员应该知其然知其所以然。
欢迎来访
- 有问题欢迎留言或加交流qq:825121848
- 转载请注明出处
- 请小编喝茶~
← SpringCloud Interview →