深入理解--Java按值传递和按引用传递
来源:互联网 发布:rpgmaker python 编辑:程序博客网 时间:2024/06/10 13:04
引言
最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路。何乐而不为?
Java按值传递和按引用传递
首先问一句: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中只有按值传递,并没有所谓的按引用传递。
基本数据类型的按值传递
java数据类型可以分为两大类:基本类型(primitive types)和引用类型(reference types)。primitive types 包括boolean类型以及数值类型(numeric types)。numeric types又分为整型(integer types)和浮点型(floating-point type)。整型有5种:byte short int long char(char本质上是一种特殊的int)。浮点类型有float和double。关系整理一下如下图:
例1
public class Swap { public static void main(String[] args) { int x = 10; int y = 20; swap(x, y); System.out.println("x(2) = " + x); System.out.println("y(2) = " + y); } public static void swap(int x, int y) { int temp = x; x = y; y = temp; System.out.println("x(1) = " + x); System.out.println("y(1) = " + y); }} /*输出 x(1) = 20 y(1) = 10 x(2) = 10 y(2) = 20 */
上面程序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并不会改变。swap执行过程图如下:
对于基本数据类型 short int long float double char byte boolean这八种按值传递调用函数并不会改变在原函数中的值。
引用数据类型的按值传递
引用数据数据类型分为三种:①接口 ②类 ③数组对于引用数据类型的按值传递先给出一个实例对比实例进行分析。
例2
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; }//输出/*a[0]=10 a[1]=20 a[0]=20 a[1]=10 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]的值发生交换。
数组、类、接口按值传递的时候都是传递对象的地址。再来看一个比较复杂的实例。
例3
public class Main{ public static void main(String[] args){ Foo f = new Foo("f"); changeReference(f); // It won't change the reference! modifyReference(f); // It will modify the object that the reference variable "f" refers to! } public static void changeReference(Foo a){ Foo b = new Foo("b"); a = b; } public static void modifyReference(Foo c){ c.setAttribute("c"); }}
①Foo f = new Foo(“f”);
②public static void changeReference(Foo a)
③changeReference(f);
④Foo b = new Foo(“b”);
⑤a = b
⑥c.setAttribute(“c”);
经典笔试题目
试题1
public class Demo { public static void main(String[] args) { //demo1 String str=new String("hello"); char []chs={'w','o','r','l','d'}; change(str, chs); System.out.println(str+" "+new String(chs)); //------------------------------------------------- //demo2 StringBuffer sb=new StringBuffer("hello"); change(sb); System.out.println(sb); } public static void change(StringBuffer sb) { sb.append(" world");// sb.deleteCharAt(0); } public static void change(String str,char[]chs) { str.replace('h', 'H'); chs[0]='W'; } }
上面程序段demo1和demo2分别输出什么,这里涉及到String特性,这道题目会做了,Java按值传递和按引用传递就彻底懂了,答案和解析先匿了。
试题2
public class foo { public static void main(String sgf[]) { StringBuffer a=new StringBuffer(“A”); StringBuffer b=new StringBuffer(“B”); operate(a,b); System.out.println(a+”.”+b); } static void operate(StringBuffer x,StringBuffer y) { x.append(y); y=x; }}
参考文献
1.https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
- 深入理解--Java按值传递和按引用传递
- 深入理解值传递和引用传递
- 【java】值传递和引用传递理解
- Java:理解Java中函数参数传递的【按值传递】和【按引用传递】
- Java按值传递和引用传递
- JAVA中参数传递(按值传递和引用传递)
- 深入分析java值传递和引用传递?
- java新手对于值传递和引用传递的理解
- 对java值传递和引用传递的一些理解
- 对java值传递和引用传递的理解
- java “值传递和引用传递”个人理解
- 自我理解关于Java的值传递和引用传递
- java值传递和引用传递的理解
- 理解Java中的引用传递和值传递
- 理解Java中的引用传递和值传递
- 理解Java中的引用传递和值传递
- 理解Java中的引用传递和值传递
- 理解Java中的引用传递和值传递
- Python正则表达式
- iOS逆向 程序获得root权限
- 欢迎使用CSDN-markdown编辑器
- lintcode --数组划分
- C语言 system函数
- 深入理解--Java按值传递和按引用传递
- 工业触摸屏-嵌入式人机界面HMI7寸 嵌入式工控一体机
- Gym
- Ignatius and the Princess I HDU
- 农具厂农具问题,三重for循环
- 信源编码作业之六:LMS最小均方算法(python)
- Train Problem II
- GIT回顾(持续更新)
- 数据结构中 图概念详解