0. 前言
以前学java是因为Hadoop是用java写的,对Hadoop生态感兴趣,就学了一点java,能看懂java程序就去看Hadoop了,但是吧,有时候又会碰到一些java不会的地方,so,就根据碰到的问题来有目的性的去学一下。
所以在此,零碎的记录一些java知识。
1. 值传递还是引用传递?
参考:
深入理解–Java按值传递和按引用传递
作者:HankingHu
来源:CSDN
原文:https://blog.csdn.net/u013309870/article/details/75499175
版权声明:本文为博主原创文章,转载请附上博文链接!
首先问一句:Is Java “pass-by-reference” or “pass-by-value”? Java到底是按值传递还是按引用传递的呢?国外的网站上关于这个问题的讨论非常之多。官方答案:The Java Spec says that everything in Java is pass-by-value. There is no such thing as “pass-by-reference” in Java. 官方的说法是在java中只有按值传递,并没有所谓的按引用传递。
1.1 先看看java中的数据类型
1.2 好,咱们来煮个栗子:
public class Swap {
public static void main(String[] args) {
int x = 10;
int y = 20;
swap(x, y);
System.out.println("x(2) = " + x); // x(2) = 10
System.out.println("y(2) = " + y); // y(2) = 20
}
public static void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
System.out.println("x(1) = " + x); // x(1) = 20
System.out.println("y(1) = " + y); // y(1) = 10
}
}
上面程序main函数调用swap函数来交换 x,y的值,然而调用函数之后发现main中x,y的值并未交换。包括在Java api中找不到一个可以交换两个变量的方法。这与Java语言的特性有关。通过一个图就可以知道上面程序的运行结果了。
(不知道函数帧的同学可以先去了解一下,我就不在这里说了。)
由上图可知,main函数中的x,y和swap函数中的x,y分别存放在不同的区域,在main中调用swap函数的时候,会将main中的x,y的值赋给swap中的x,y。当swap函数中对x,y交换时只是对swap帧中的x,y做交换,并不会改变main中的x,y。所以当函数返回时main中的x,y并不会改变。
所以,对于基本数据类型中八种按值传递调用函数并不会改变在原函数中的值。
1.3 再看引用数据类型的栗子:
public static void main(String[] args) {
int []a={10,20};
System.out.println("a[0] :"a[0]+"a[1] : "+a[1]); //a[0]=10,a[1]=20;
swap(a, 0, 1);
System.out.println("a[0] :"a[0]+"a[1] : "+a[1]); //a[0]=20,a[1]=10;
}
public static void swap(int []a,int i,int j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
System.out.println("a[0] :"a[0]+"a[1] : "+a[1]); //a[0]=20,a[1]=10;
}
运行程序后发现,swap函数对a[0] ,a[1]的操作竟然影响到了main函数中的a[0] ,a[1]的值,真是不可思议。
为什么会产生如此之结果?
原来引用类型的按值传递,传递的是对象的地址。还是用图来解释一下。
由图可以看出在swap中仅仅是得到了数组的地址,并没有对数组的元素进行复制,在swap中对数组的操作是直接对main函数中数组的操作,因此swap函数返回后main函数中的a[0] ,a[1]的值发生交换。
所以,数组、类、接口按值传递的时候都是传递对象的地址。