-
2019-04-07 20:47:43
Java方法中,值传递和地址传递一直让我很迷惑,最近认真看了看资料分析了一下,供大家参考。
01 首先看题目:
public class test { public static void main(String[] args) { String str1="abc"; char[]str2={'a','b','c'}; exChange1(str1,str2 ); System.out.println(str1); System.out.println(new String(str2)); StringBuffer sb1=new StringBuffer("A"); StringBuffer sb2=new StringBuffer("B"); exChange2(sb1,sb2 ); System.out.println(sb1.toString()); System.out.println(sb2.toString()); } private static void exChange2(StringBuffer sb01,StringBuffer sb02){ sb01=sb02; sb01.append(sb02); } private static void exChange1(String str1,char[]str2){ str1="gbc"; str2[0]='g'; } }
题目的答案
abc gbc A BB
分析过程
02 理解定义
值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。
引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
a.传递值的数据类型:八种基本数据类型和String(这样理解可以,但是事实上String也是传递的地址,只是string对象和其他对象是不同的,string对象是不能被改变的,内容改变就会产生新对象。那么StringBuffer就可以了,但只是改变其内容。不能改变外部变量所指向的内存地址)。
b.传递地址值的数据类型:除String以外的所有复合数据类型,包括数组、类和接口参考:https://blog.csdn.net/maoyeqiu/article/details/49250339
03 值传递实例
public class Test { public static void change(int i, int j) { int temp = i; i = j; j = temp; } public static void main(String[] args) { int a = 3; int b = 4; change(a, b); System.out.println("a=" + a); System.out.println("b=" + b); }
结果: a=3 b=4
解释:值传递,在调用方法change(a,b)相当于省略了 i=a,j=b。在这一步之后,方法change里面对 i 和 j 的操作与a、b是无关的。
04 引用传递
public class Test { public static void change(int[] arr2) { arr2[0] = 6; } public static void main(String[] args) { int[] arr = { 1, 2, 3, 4, 5 }; change(arr); System.out.println(arr[0]); }
结果: 6
解释: 地址传递。通过方法change,将 arr 的地址传递给了 arr2 ,在方法change里,改变了 arr[ 0 ]地址的指向,结果会影响到 arr
可以将“地址” 理解为一个盒子,change方法,让arr2有了权限去操作盒子,将盒子里的东西换了。05 原题分析
string是值传递,所有方法 exchange1,对str1操作与最初定义的str1是无关的。str1的值不变,为abc;
数据是地址传递,更改了最初的str2[ 0 ]的地址所指向的值,str2[ 0 ]的值改变,gString str1="abc"; char[]str2={'a','b','c'}; exChange1(str1,str2 ); ----------------- private static void exChange1(String str1,char[]str2){ str1="gbc"; str2[0]='g'; } }
StringBuffer 是地址传递(只要不是八大基本数据类型和string,其他都是地址传递)。
01)首先,方法 exChange2,将最初的sb1的地址传给了方法里的sb01,sb2的地址给了sb02;
02) 然后,sb01=sb02 : 将sb02的地址给了sb01(也就是说,这个时候,sb01和sb02的地址是一样的,都是sb2的了),值都为“B”;
03)sb01.append(sb02),操作的实际对象是sb2的地址,所以与sb1无关。sb1的值不变
, sb2的值发生改变StringBuffer sb1=new StringBuffer("A"); StringBuffer sb2=new StringBuffer("B"); exChange2(sb1,sb2 ); System.out.println(sb1.toString()); System.out.println(sb2.toString()); } private static void exChange2(StringBuffer sb01,StringBuffer sb02){ sb01=sb02; sb01.append(sb02); } }
这个代码运行结果为:
abc gbc A BB
更多相关内容 -
为什么Java只有值传递
2021-01-20 02:08:46我们先看一下值传递和引用传递的概念和区别 值传递:是指在调用函数时将实际参数复制一份传递到函数中,...我们通过例子理解一下Java的值传递: public static void main(String[] args) { int a = 10; int b = 20; -
详解java的值传递、地址传递、引用传递
2020-08-30 03:50:31主要介绍了详解java的值传递、地址传递、引用传递的相关资料,需要的朋友可以参考下 -
Java:值传递与地址传递(引用传递)区别
2018-08-15 17:35:10值传递(pass by value)是指在调用函数时将实际参数 复制 一份传递到函数中,这样在函数中如果对 参数 进行修改,将不会影响到实际参数。传递对象往往为整型浮点型字符型等基本数据结构。 public class PassBy...值传递(pass by value)是指在调用函数时将实际参数 复制 一份传递到函数中,这样在函数中如果对 参数 进行修改,将不会影响到实际参数。传递对象往往为整型浮点型字符型等基本数据结构。
public class PassByValueReference { //值传递 public static void main(String[] args) { int x = 9; pass(x); System.out.println(x); } private static void pass(int y) { System.out.println(y); y=0; } }
下为运行结果:(整型y的值变化没有影响整型x的值)
地址传递(pass by reference)是指在调用函数时将实际参数的地址 直接 传递到函数中,那么在函数中对 参数 所进行的修改,将影响到实际参数。(类似于共同体) 传递对象往往为数组等地址数据结构。
public class PassByValueReference { //地址(引用)传递 public static void main(String[] args) { int [] x = {9}; System.out.println(x[0]); pass(x); System.out.println(x[0]); } public static void pass(int [] y) { y[0] = 0; } }
下为运行结果:(数组y的值变化同时影响数组x的值)
(值传递与引用传递在计算机数据结构中用到了栈与堆的知识)
另外,如果还没接触Java中的函数与方法相关知识的,可简单借助赋值理解:(运行结果与上面类似)
public class PassByValueReference { //值传递(赋值非函方式) public static void main(String[] args) { int x = 9; System.out.println(x); y = x; y = 10; System.out.println(x); } }
这里x与y就是基本数据类型,赋值后把x的值传给了y,相当于是复制了一份副本,而不是把整个x(即x地址)给了y。
public class PassByValueReference { //地址传递(赋值非函方式) public static void main(String[] args) { int [] x = {1}; System.out.println(x[0]); int [] y = x; y[0] = 0; System.out.println(x[0]); } }
这里x与y是数组,这次的代码中不是简单地令x[0]=y[0],而是直接令x=y,此赋值语句把x的数组地址都给了y,相当于是在“同一条船上”了,一起发生变化,y[0]变了同时x[0]也改变。
-
Java中的值传递和地址传递(传值、传引用)
2021-02-12 15:09:20更何况,要想知道Java到底是传值还是传引用,起码你要先知道传值和传引用的准确含义吧?可是如果你已经知道了这两个名字的准确含义,那么你自己就能判断Java到底是传值还是传引用。这就好像用大学的名词来解释高中的...首先,不要纠结于 Pass By Value 和 Pass By Reference 的字面上的意义,否则很容易陷入所谓的“一切传引用其实本质上是传值”这种并不能解决问题无意义论战中。
更何况,要想知道Java到底是传值还是传引用,起码你要先知道传值和传引用的准确含义吧?可是如果你已经知道了这两个名字的准确含义,那么你自己就能判断Java到底是传值还是传引用。
这就好像用大学的名词来解释高中的题目,对于初学者根本没有任何意义。
一:搞清楚 基本类型 和 引用类型的不同之处
int num = 10;
String str = "hello";
<img src="https://pic2.zhimg.com/166032bc90958c21604110441ad03f45_b.jpg" data-rawwidth="728" data-rawheight="458" class="origin_image zh-lightbox-thumb" width="728" data-original="https://pic2.zhimg.com/166032bc90958c21604110441ad03f45_r.jpg">如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。
如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。
二:搞清楚赋值运算符(=)的作用
num = 20;
str = "java";
<img src="https://pic3.zhimg.com/287c0efbb179638cf4cf27cbfdf3e746_b.jpg" data-rawwidth="714" data-rawheight="572" class="origin_image zh-lightbox-thumb" width="714" data-original="https://pic3.zhimg.com/287c0efbb179638cf4cf27cbfdf3e746_r.jpg">对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。
如上图所示,"hello" 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)
三:调用方法时发生了什么?参数传递基本上就是赋值操作。
第一个例子:基本类型
void foo(int value) {
value = 100;
}
foo(num); // num 没有被改变
第二个例子:没有提供改变自身方法的引用类型
void foo(String text) {
text = "windows";
}
foo(str); // str 也没有被改变
第三个例子:提供了改变自身方法的引用类型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。
第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。
重点理解为什么,第三个例子和第四个例子结果不同?
下面是第三个例子的图解:
<img src="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_b.jpg" data-rawwidth="772" data-rawheight="398" class="origin_image zh-lightbox-thumb" width="772" data-original="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_r.jpg">builder.append("4")之后
builder.append("4")之后
<img src="https://pic4.zhimg.com/ff2ede9c6c55568d42425561f25a0fd7_b.jpg" data-rawwidth="696" data-rawheight="424" class="origin_image zh-lightbox-thumb" width="696" data-original="https://pic4.zhimg.com/ff2ede9c6c55568d42425561f25a0fd7_r.jpg">下面是第四个例子的图解:
下面是第四个例子的图解:
<img src="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_b.jpg" data-rawwidth="772" data-rawheight="398" class="origin_image zh-lightbox-thumb" width="772" data-original="https://pic4.zhimg.com/d8b82e07ea21375ca6b300f9162aa95f_r.jpg">
builder = new StringBuilder("ipad"); 之后
<img src="https://pic2.zhimg.com/46fa5f10cc135a3ca087dae35a5211bd_b.jpg" data-rawwidth="710" data-rawheight="438" class="origin_image zh-lightbox-thumb" width="710" data-original="https://pic2.zhimg.com/46fa5f10cc135a3ca087dae35a5211bd_r.jpg">
作者:Intopass
链接:https://www.zhihu.com/question/31203609/answer/50992895
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Java传递参数有两种方式:值传递和引用传递
值传递是传递数据:如基本数据类型都是值传递
引用传递是把形参和实参的指针指向了堆中的同一对象,对象的引用和数组的引用。
实参,Java的基本数据类型,如int,double等在函数的参数传递时,传递的是副本。String也属于这一范畴。
形参,而如果是对象,则传递的是引用。
作者:fbysss
msn:jameslastchina@hotmail.com
blog:blog.csdn.net/fbysss
声明:本文由fbysss原创,转载请注明出处
关键字:Java 传值 传引用
这是个老生常谈的问题了,引起过无数争论,但可以说一直没有一个令人满意的回答。
有些人非要故弄玄虚,把传引用说成是栈里面放的是引用的值,说只有传值没有传引用,那看看这句经典名言吧:
O'Reilly's Java in a Nutshell by David Flanagan (see Resources) puts it best: "Java manipulates objects 'by reference,' but it passes object references to methods 'by value.'"
从这里也可以看到,David 也没那么生硬,不过是看你从哪个角度来认识这个问题,如果大家习惯c++的那种传参时的理解方式,为何不能这么比较呢?
有人已经总结过:
参见
1、对象是按引用传递的
2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本写的没错,但是文字太多,第二条就已经把人弄糊涂了,得仔细看完4条才清楚。而且对String类型的疑惑没有解决。
这么简单的事情,何必这么绕呢?为啥没人跟c++过不去,偏要跟Java来劲?
三句话总结一下:
1.对象就是传引用
2.原始类型就是传值
3.String等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。
其他参考文章:
-
java中的值传递和引用传递
2021-12-07 20:07:09一般java中的基础类型数据传递都是值传递。 引用传递(Pass By Reference或者Call By Reference)一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。一般java中实例(包装)对象的传递...个人理解,可能会有错误之处,请仔细甄别,谨慎参考!如有错误或不同见解请指出!
值传递(Pass By Value或者Call By Value)是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。一般java中的基础类型数据传递都是值传递。
引用传递(Pass By Reference或者Call By Reference)一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。一般java中实例(包装)对象的传递是引用传递。一、基本类型和引用类型在内存中的不同之处
int num = 10; String str = "hello";
如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。二、赋值时内存的变化
int num = 24; String str = "world";
对于基本类型num,赋值运算符会直接改变变量的值,原来的值被覆盖掉。对于引用类型str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象(“hello” 字符串对象)不会被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)
三、调用方法时发生了什么,参数传递基本上就是赋值操作第一个例子:基本类型
void change(int value) { value = 100; } change(num); // num 没有被改变
第二个例子:引用类型没有使用改变自身方法的方法
void change(String a) { a = "唐"; } change(str); // str没有被改变
或:
StringBuilder stri = new StringBuilder("唐"); void change(StringBuilder builder) { builder = new StringBuilder("宋"); } change(stri); // stri没有被改变,还是 "唐"。
第三个例子:引用类型使用了改变自身方法的方法
StringBuilder stri = new StringBuilder("明"); void change(StringBuilder builder) { builder.append("清"); } change(stri); // stri被改变了,变成了"清"。
第三个例子的图解:
builder.append("清")之后参考:
-
Java值传递与引用传递的区别
2021-09-09 22:55:57Java值传递与引用传递 文章目录Java值传递与引用传递前景实参与形参值传递与引用传递Java中的值...错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。 错误 -
值传递 和 地址传递 的区别(好多句话才可以说清)
2020-02-23 11:34:41要知道什么是**值传递**和**地址传递**,首先要知道什么是**基本数据类型**和**引用类型**。 Java的基本数据类型就八种(除了这八种之外都是引用类型): ◆整型:byte(8位) short(16位) int(32位) long(64位); ... -
Java中是值传递和引用传递
2022-01-15 12:22:33Java中只有值传递 首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。 按值调用(call by value):表示方法接收的是调用者提供的值。 按引用调用(call by reference):表示方法接收... -
java中只有值传递
2014-07-21 16:34:25Java中传递对象时传递的并不是对象中的内容, 而是对象的地址。 -
java的值传递和引用传递
2021-02-26 08:26:02昨天博主在对于值传递和引用传递这里栽了一个大坑啊,导致一下午时间都浪费在这里,我们先说下值传递和引用传递java官方解释:值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式... -
Java 是值传递还是引用传递
2019-03-20 02:40:16最近整理面试题,整理到值传递、引用传递,到网上搜了一圈,争议很大。带着一脸蒙圈,线上线下查了好多资料。最终有所收获,所以分享给大家,希望能对...当然如果针对 Java 语言本身来讲,Java 中只有 值传递,没有... -
java中的参数传递(只有值传递没有引用传递)
2019-07-31 19:25:14Java中只有传值调用(值传递),没有传址调用(址传递或者引用传递)。所以在java方法中改变参数的值是不会改变原变量的值的,但为什么改变引用变量的属性值却可以呢?请看下面的解答。 java中的数据类型 Java中... -
JAVA值传递还是引用传递?
2022-03-12 14:20:28结论:java是值传递,只是, 对于基本数据类型,传递的是基本类型的量值的拷贝 对于引用类型,传递的是该引用所指向的对象在内存中的地址值的拷贝 实参和形参 public static void test(String s){ System.out.... -
Java值传递和引用传递详细说明
2020-07-14 15:53:17学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java只有值传递,... -
Java 值传递与“引用传递”
2020-02-09 14:23:35Java 的值传递2. Java 的引用传递 1. Java 的值传递 通常认为Java 方法传参数都是值传递 2. Java 的引用传递 传入引用类型的数据,可以修改数据内容,但是在方法中对传入引用的再赋值不会生效 ... -
java中的值传递和引用传递的区别?
2018-11-29 21:04:511.值传递概念:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 实例: public class Main { public static void main(String[] args) { int ... -
Java值传递和地址传递:关于String类型和集合类型作为函数参数时传值问题的测试
2017-02-15 15:18:17* 测试字符串和集合在函数之间的传值问题,解决值传递和地址传递的疑惑. */ private static void testTransmitValue(String transmitValue, String transmitValueNew, List<String> list, Integer integer) { ... -
Java值传递问题分析解决
2022-04-28 16:13:40Java值传递问题分析解决 -
Java值传递
2020-11-07 15:47:47这篇文章中,我从什么是方法的实际参数和形式参数开始,给你讲解为什么说Java中只有值传递。 辟谣时间 关于这个问题,在StackOverflow上也引发过广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同,甚至很多... -
Java参数传递详解——值传递还是址传递?
2019-11-28 21:57:57Java参数传递——值传递还是址传递? 首先是变量的存储方式 各种变量的存储方式: 基本数据类型: int age = 20; 变量名age和值20都存储在jvm栈中 引用数据类型: 字符串见 ... -
深入理解--Java按值传递和按引用传递
2017-07-20 15:48:49引言最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路。何乐而不为?Java按... -
数组是通过值传递还是通过Java引用传递?
2021-03-14 19:09:29数组不是Java中的原始类型,但它们也不是对象,所以它们是通过值传递还是通过引用传递?它是否依赖于数组包含的内容,例如引用或基元类型?数组是对象,是的,但是Java中的任何东西都不是通过引用传递的。所有参数... -
Java 值传递 & 引用传递 引发的思考
2019-12-21 20:57:24这是一篇正经又带点幽默的文章,希望各位观众老爷们喜欢。 Java 到底是值传递还是引用传递,这是一个问题。 本文先由概念出发,穿插Java内存结构,最后举例探讨该问题。 -
Java的值传递
2021-08-12 21:47:31一、值传递和引用传递 在程序设计语言中将参数传给方法或函数的方式目前有两种:一种是值传递,一种是引用传递。 值传递表示将实参的值传递给方法;引用传递表将实参a的地址引用传递给方法。 Java是采用值传递的... -
Java中的参数传递,到底是值传递还是引用传递?
2020-05-12 18:23:29错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。 错误理解二:Java是引用传递。 错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,... -
JAVA参数传递方式 (按值传递与引用传递区别)
2018-09-30 22:58:30首先要明确的是JAVA中没有引用传递, 全部是按值调用 令大家所费解的 当对象引用作为参数时 函数为什么能修改真实的对象呢?这不是引用传递的特征吗? 尤其先学习C++再学习JAVA的同学(比如说我自己)会这样认为, 用... -
JAVA参数传递的两种方式的区别:直接(值)传递和引用传递
2021-08-16 21:35:56Java中的值传递和引用传递 在Java中有很多的传递方式,就比如我们今天要说的值传递和引用传递。 其实在日常的学习中我们在敲代码的过程中会遇到这样一种情况 1、我们传递参数到对应方法里,然后通过方法里的一系列...