Java中传值与传引用的三种情况
- 格式:doc
- 大小:153.50 KB
- 文档页数:12
函数调用时参数传递方式在编程语言中,函数是一段可重用的代码块,可以被其他部分调用和执行。
函数的参数是在调用函数时传递给函数的信息。
参数传递的方式不同,可以分为值传递、引用传递和指针传递。
1.值传递(传值调用):值传递是指将实际参数的值复制给形式参数,形式参数在函数内部使用时是独立的变量,对形参进行修改不会影响实参的值。
值传递适用于不需要修改实参的情况和使用简单数据类型作为参数的情况。
值传递的特点是速度相对较快,但当传递大对象时会占用较多的内存和时间。
2.引用传递(传引用调用):引用传递是指将实际参数的引用传递给形式参数,形式参数在函数内部使用时是实参的别名,对形参的修改会影响到实参的值。
引用传递适用于需要修改实参的情况和使用复杂数据类型作为参数的情况。
引用传递的特点是可以节省内存和时间,但是有可能会对实参造成不可预期的修改。
3.指针传递:指针传递是指将实际参数的指针传递给形式参数,在函数内部使用指针来访问实参的值。
指针传递适用于需要修改实参的情况和需要进行动态内存分配的情况。
指针传递的特点是可以直接通过指针修改实参的值,但是需要注意指针的合法性和空指针的处理。
不同的编程语言会有不同的参数传递方式,默认情况下,大多数编程语言采用值传递的方式。
而在一些编程语言中,也可以通过特定的语法来实现引用传递或者指针传递。
在C语言中,函数的参数传递方式是值传递。
函数参数的值会被复制到对应的形式参数中,形式参数在函数内部修改不会影响实际参数的值。
如果需要在函数内部修改实际参数,可以通过传递指针或引用的方式来实现。
在C++中,函数的参数传递方式可以通过关键字来显式地指定。
默认情况下,C++采用值传递的方式,但可以使用引用传递或指针传递来实现对实际参数的修改。
引用传递使用引用类型作为参数,可以直接对实际参数进行修改。
指针传递使用指针类型作为参数,通过指针来访问实际参数的值。
在Java中,函数的参数传递方式是值传递。
所有的参数都是按值传递,包括基本数据类型和对象引用。
java传值与传引用的三种情况大家先看一个例子:public class Example{String str=new String("good");char[]ch={'a','b','c'};public static void main(String args[]){Example ex=new Example();ex.change(ex.str,ex.ch);System.out.print(ex.str+" and ");System.out.print(ex.ch);}public void change(String str,char ch[]){str="test ok";ch[0]='g';}}看看输出结果?good and gbcjava中没有了c++中这样的引用符号,也没像c#中那样提供了out与ref 那么它是怎么做的呢做什么事情都要去除例外的东西,String类就是此类问题的一个特殊情况为什么特殊呢?因为它是一个引用类型,确执行的是值传递。
这样说有些抽象,还是举个例子吧值传递:class Str{public static void main(String[] args){int i = 900;System.out.println(i);changeInt(i);System.Out.println(i);}public static void changeInt(int s){s = 34234;}}结果:900900这就是所谓的值传递。
i把自己的副本给了函数changeInt的形参,而在changeInt中虽然将s赋值34234。
但是对原来的i值并没有影响,因为它所修改的只是i的copy品而已。
引用传递:class Str{public static void main(String[] args){Yinyong y = new Yinyong();System.Out.println(y.age);changeObject(y);System.Out.println(y.age);}public static void changeObject(Yinyong obj){Obj.age = 34234;}}class Yinyong{int age = 22;}声明了个简单的类Yinyong,当把Yinyong的对象y传递给函数changeObject后,看下前后结果:2234234值被改变了,这就是引用调用。
java方法引用传递【最新版】目录1.Java 方法引用的概述2.Java 方法引用的传递方式3.Java 方法引用的优点4.Java 方法引用的示例正文一、Java 方法引用的概述Java 方法引用是一种在 Java 编程语言中调用方法的简化方式。
通过方法引用,可以简化代码,提高代码的可读性和可维护性。
方法引用实际上是方法的引用,可以将方法名作为一个变量来使用。
二、Java 方法引用的传递方式Java 方法引用的传递方式主要有以下几种:1.值传递:将方法引用作为一个值传递给另一个变量。
这种方式不会影响原方法的引用。
2.引用传递:将方法引用作为一个引用传递给另一个变量。
这种方式会改变原方法的引用。
3.指针传递:将方法引用的地址作为一个指针传递给另一个变量。
这种方式同样会改变原方法的引用。
三、Java 方法引用的优点Java 方法引用具有以下优点:1.代码简洁:方法引用使得调用方法的代码更加简洁,提高了代码的可读性。
2.减少出错:方法引用可以减少手动调用方法时出现的错误,例如拼写错误等。
3.提高代码可维护性:方法引用使得代码更加简洁,有利于代码的维护和修改。
四、Java 方法引用的示例以下是一个 Java 方法引用的示例:```javapublic class MethodReferenceExample {public static void main(String[] args) {// 方法引用的值传递Runnable runnable1 = () -> System.out.println("Hello, World!");Runnable runnable2 = runnable1;runnable2.run(); // 输出 "Hello, World!"// 方法引用的引用传递Runnable runnable3 = () -> System.out.println("Hello, World!");Runnable runnable4 = runnable3;runnable4.run(); // 输出 "Hello, World!"runnable3.run(); // 输出 "Hello, World!"// 方法引用的指针传递Runnable runnable5 = () -> System.out.println("Hello, World!");Runnable runnable6 = runnable5;runnable5.run(); // 输出 "Hello, World!"runnable6.run(); // 输出 "Hello, World!"}}```本示例中,我们定义了多个方法引用,并通过不同的传递方式调用它们。
java 值传递与引用传递的详细理解在 Java 中,参数传递是一个非常重要的概念,不同的参数传递方式会对程序的行为产生不同的影响。
Java 中的参数传递分为值传递和引用传递两种。
其中,值传递是指将对象的引用作为参数传递给方法,方法内部对这个引用进行操作,从而改变原始对象的状态;而引用传递则是将对象本身作为参数传递给方法,方法内部对这个对象进行操作,从而改变原始对象的状态。
值传递和引用传递的本质区别在于变量存储的是对象的引用还是对象本身的值。
在 Java 中,基本类型都是值类型,即它们存储的是它们的值,当一个基本类型的对象作为参数传递给方法时,方法内部只是对这个对象的值进行操作,而不会影响到原始对象的值。
而对于引用类型,它们存储的是对象本身的地址,当一个引用类型的对象作为参数传递给方法时,方法内部只是对这个对象的地址进行操作,即改变引用的地址,那么原始对象就被覆盖了,也就是说,引用传递会导致原始对象被覆盖或者改变。
在实际的编程中,值传递和引用传递的使用要根据具体的情况来决定。
一般来说,对于基本类型,建议使用值传递,因为基本类型的值本身就包含了它们的值,没有必要再进行引用传递;而对于引用类型,建议使用引用传递,因为引用类型的对象本身就包含了对象本身的地址,引用传递可以更好地保护原始对象的状态。
Java 中的参数传递是一个非常重要的概念,不同的参数传递方式会对程序的行为产生不同的影响。
Java 中的参数传递分为值传递和引用传递两种。
值传递是指将对象的引用作为参数传递给方法,方法内部对这个引用进行操作,从而改变原始对象的状态;而引用传递则是将对象本身作为参数传递给方法,方法内部对这个对象进行操作,从而改变原始对象的状态。
值传递和引用传递的本质区别在于变量存储的是对象的引用还是对象本身的值。
值类型和引用类型的区别是什么值类型和引用类型经常出现在JAVA等编程语言的书籍中,一些学习java的新手不是很懂这两者的区别,下面小编为大家介绍值类型和引用类型的区别,感兴趣的朋友们一起来看看吧!值类型和引用类型的区别一、定义值类型表示复制一个当前变量传给方法,当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变。
引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是传入的变量的值也将改变。
通俗说法: 值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。
----(摘自网上)值类型和引用类型的区别二、基本数据类型值类型有四类八种四类: 1,整型 2,浮点型 3,字符型 4,逻辑型八种: 1,整型3种 byte,short,int,long2,浮点型2种 float,double3,字符型1种 char4,逻辑型1种 boolean引用类型除了四类八种基本类型外,所有的类型都称为引用类型。
值类型和引用类型的区别三、值传递和引用传递值传递基本数据类型赋值都属于值传递,值传递传递的是实实在在的变量值,是传递原参数的拷贝,值传递后,实参传递给形参的值,形参发生改变而不影响实参。
引用传递引用类型之间赋值属于引用传递。
引用传递传递的是对象的引用地址,也就是它的本身(自己最通俗的理解)。
引用传递:传的是地址,就是将实参的地址传递给形参,形参改变了,实参当然被改变了,因为他们指向相同的地址。
引用和我们的指针差不多,但是它不又不需要我们去具体的操作。
值类型和引用类型的区别四、内存分配一个具有值类型(value type)的数据存放在栈内的一个变量中。
即是在栈中分配内存空间,直接存储所包含的值,其值就代表数据本身。
值类型的数据具有较快的存取速度。
一个具有引用类型(reference type)的数据并不驻留在栈中,而是存储于堆中。
java中值类型和引⽤类型的区别 简单分类,java中除了值类型就是对象。
值类型就是java中的基本类型,⽽除了这些基本类型都是对象。
关于java中值类型和引⽤类型的区别都是很明显的。
下⾯是店铺为⼤家准备的java中值类型和引⽤类型的区别,希望⼤家喜欢! java中值类型和引⽤类型的区别篇⼀ 值类型通常被分配在栈上,它的变量直接包含变量的实例,使⽤效率⽐较⾼。
java中值类型和引⽤类型的区别篇⼆ 引⽤类型分配在托管堆上,引⽤类型的变量通常包含⼀个指向实例的指针,变量通过该指针来引⽤实例。
java中值类型和引⽤类型的区别篇三 值类型继承⾃ValueType(注意:⽽System.ValueType⼜继承⾃System.Object);⽽引⽤类型继承⾃System.Object。
java中值类型和引⽤类型的区别篇四 值类型变量包含其实例数据,每个变量保存了其本⾝的数据拷⻉(副本),因此在默认情况下,值类型的参数传递不会影响参数本⾝;⽽引⽤类型变量保存了其数据的引⽤地址,因此以引⽤⽅式进⾏参数传递时会影响到参数本⾝,因为两个变量会引⽤了内存中的同⼀块地址。
java中值类型和引⽤类型的区别篇五 值类型有两种表⽰:装箱与拆箱;引⽤类型只有装箱⼀种形式。
我会在下节以专⻔的篇幅来深⼊讨论这个话题。
java中值类型和引⽤类型的区别篇六 典型的值类型为:struct,enum以及⼤量的内置值类型;⽽能称为类的都可以说是引⽤类型。
java中值类型和引⽤类型的区别篇七 值类型的内存不由GC(垃圾回收,Gabage Collection)控制,作⽤域结束时,值类型会⾃⾏释放,减少了托管堆的压⼒,因此具有性能上的优势。
例如,通常struct⽐class更⾼效;⽽引⽤类型的内存回收,由GC 来完成,微软甚⾄建议⽤户最好不要⾃⾏释放内存。
java中值类型和引⽤类型的区别篇⼋ 值类型是密封的(sealed),因此值类型不能作为其他任何类型的基类,但是可以单继承或者多继承接⼝;⽽引⽤类型⼀般都有继承性。
java中值传递和引用传递区别2011-07-09 18:48【转】java中值传递和引用传递区别java中的八大基本数据类型:int long float double short byte char boolean看似一样的方法,程序输出的结果却不太一样。
changeObj()方法真正的把输入的参数改变了,而changePri()方法对输入的参数没有任何的改变。
从这个例子知道Java对对象和基本的数据类型的处理是不一样的。
和C语言一样,当把Java的基本数据类型(如int,char,double等)作为入口参数传给函数体的时候,传入的参数在函数体内部变成了局部变量,这个局部变量是输入参数的一个拷贝,所有的函数体内部的操作都是针对这个拷贝的操作,函数执行结束后,这个局部变量也就完成了它的使命,它影响不到作为输入参数的变量。
这种方式的参数传递被称为"值传递"。
而在Java中用对象的作为入口参数的传递则缺省为"引用传递",也就是说仅仅传递了对象的一个"引用",这个"引用"的概念同C语言中的指针引用是一样的。
当函数体内部对输入变量改变时,实质上就是在对这个对象的直接操作。
class MyDemo {public static void operate(StringBuffer x, StringBuffer y) {x.append(y);y = x;System.out.println(x + "," + y);}public static void main(String[] args) {StringBuffer a = new StringBuffer("A");StringBuffer b = new StringBuffer("B");operate(a, b);System.out.println(a + "," + b);}}结果:AB,ABAB,B解释:很明显你这里传递的是地址(引用)传递2个StringBuffer 对象!注意啦:x 会指向a 所指向的内存(可以理解为都指向A),y 会指向b 所指向的内存,(可以理解为都指向B)x.append(y); //这句话把y 指向的值追加给x指向的值,这个时候x 和a 指向的内存都是AB,y指向的内存仍然是By=x;//这句话就是把x 的值附值给y,附的是地址!这样a,y,x 同时值向AB,b仍然指向BSystem.out.println(x+","+y); 这里所以打印AB,ABSystem.out.println(a+","+b); 这里所以打印AB ,B引用参数的传递是把原来的地址传递给新的变量,原来引用的仍然在那里!下面还是例子://在函数中传递基本数据类型,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=3b=4原因就是参数中传递的是基本类型 a 和 b 的拷贝,在函数中交换的也是那份拷贝的值而不是数据本身;public class Test {public static void change(int[] counts) {counts[0] = 6;System.out.println(counts[0]);}public static void main(String[] args) {int[] count = { 1, 2, 3, 4, 5 };change(count);}}结果是:6在方法中传递引用数据类型int数组,实际上传递的是其引用count的拷贝,他们都指向数组对象,在方法中可以改变数组对象的内容。
java传值与传引用的三种情况大家先看一个例子:public class Example{String str=new String("good");char[]ch={'a','b','c'};public static void main(String args[]){Example ex=new Example();ex.change(ex.str,ex.ch);System.out.print(ex.str+" and ");System.out.print(ex.ch);}public void change(String str,char ch[]){str="test ok";ch[0]='g';}}看看输出结果? good and gbcjava中没有了c++中这样的引用符号,也没像c#中那样提供了out与ref 那么它是怎么做的呢做什么事情都要去除例外的东西,String类就是此类问题的一个特殊情况为什么特殊呢?因为它是一个引用类型,确执行的是值传递。
这样说有些抽象,还是举个例子吧值传递:class Str{public static void main(String[] args){int i = 900;System.out.println(i);changeInt(i);System.Out.println(i);}public static void changeInt(int s){s = 34234;}}结果:900900这就是所谓的值传递。
i把自己的副本给了函数changeInt的形参,而在changeInt中虽然将s赋值34234。
但是对原来的i值并没有影响,因为它所修改的只是i的copy品而已。
引用传递:class Str{public static void main(String[] args){Yinyong y = new Yinyong();System.Out.println(y.age);changeObject(y);System.Out.println(y.age);}public static void changeObject(Yinyong obj){Obj.age = 34234;}}class Yinyong{int age = 22;}声明了个简单的类Yinyong,当把Yinyong的对象y传递给函数changeObject后,看下前后结果:2234234值被改变了,这就是引用调用。
下面再看看传递String对象会发生什么结果?class Str{public static void main(String[] args){String s = "java test";System.Out.println(s);changeString(s);System.out.println(s);}public static void changeString(String str){str = "3gg over right";}}看看结果吧:java testjava test你惊奇的发现s的值并没有改变!你会问了,String不也是引用类型的吗?怎么它的值没有改变呢?因为是这样的:String被设计为不可修改的类型,也就是对String对象的任何修改都将重新创建一个对象而放弃以前的内存空间的引用!如上例:比如 s指向0x2344,当它赋值给str时str也同样指向了0x2344。
而当执行str="3gg over right"后,str指向了别的地方。
也许是0x2222或者其他,反正不是0x2344了。
所以当你输出s的时候,它的值并没有被修改!综上所述:基本数据类型传递的是值的拷贝;对象类型传递的是引用的拷贝;而String类型传递的虽然也是对象,但它不同于一般的对象类型,它String 被设计为不可修改的类型,也就是对String对象的任何修改都将重新创建一个对象而放弃以前的内存空间的引用!按值传递还是按引用传递这个在Java里面是经常被提起的问题,也有一些争论,似乎最后还有一个所谓的结论:“在Java里面参数传递都是按值传递”。
事实上,这很容易让人迷惑,下面先分别看看什么是按值传递,什么是按引用传递,只要能正确理解,至于称作按什么传递就不是个大问题了。
1:按值传递是什么指的是在方法调用时,传递的参数是按值的拷贝传递。
示例如下:public class TempTest {private void test1(int a){//做点事情}public static void main(String[] args) {TempTest t = new TempTest();int a = 3;t.test1(a);//这里传递的参数a就是按值传递}}按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。
示例如下:public class TempTest {private void test1(int a){a = 5;System.out.println("test1方法中的a==="+a);}public static void main(String[] args) {TempTest t = new TempTest();int a = 3;t.test1(a);//传递后,test1方法对变量值的改变不影响这里的aSystem.out.println(”main方法中的a===”+a);}}运行结果是:test1方法中的a===5main方法中的a===32:按引用传递是什么指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。
示例如下:public class TempTest {private void test1(A a){}public static void main(String[] args) {TempTest t = new TempTest();A a = new A();t.test1(a); //这里传递的参数a就是按引用传递}}class A{public int age = 0;}3:按引用传递的重要特点传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。
示例如下:第1行 public class TempTest {第2行 private void test1(A a){第3行 a.age = 20;第4行 System.out.println("test1方法中的age="+a.age);第5行 }第6行 public static void main(String[] args) {第7行 TempTest t = new TempTest();第8行 A a = new A();第9行 a.age = 10;第10行 t.test1(a);第11行System.out.println(”main方法中的age=”+a.age);第12行 }第13行 }第14行 class A{第15行 public int age = 0;第16行 }运行结果如下:test1方法中的age=20main方法中的age=204:理解按引用传递的过程——内存分配示意图要想正确理解按引用传递的过程,就必须学会理解内存分配的过程,内存分配示意图可以辅助我们去理解这个过程。
用上面的例子来进行分析:(1):运行开始,运行第8行,创建了一个A的实例,内存分配示意如下:(2):运行第9行,是修改A实例里面的age的值,运行后内存分配示意如下:(3):运行第10行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。
请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。
内存分配示意如下:由于是按引用传递,也就是传递的是内存空间的地址,所以传递完成后形成的新的内存示意图如下:也就是说:是两个变量都指向同一个空间。
(4):运行第3行,为test1方法中的变量a指向的A实例的age进行赋值,完成后形成的新的内存示意图如下:此时A实例的age值的变化是由test1方法引起的(5):运行第4行,根据此时的内存示意图,输出test1方法中的age=20 (6):运行第11行,根据此时的内存示意图,输出main方法中的age=205:对上述例子的改变理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢?就是test1方法里面的修改不影响到main方法里面呢?方法是在test1方法里面新new一个实例就可以了。
改变成下面的例子,其中第3行为新加的:第1行 public class TempTest {第2行 private void test1(A a){第3行 a = new A();//新加的一行第4行 a.age = 20;第5行 System.out.println("test1方法中的age="+a.age);第6行 }第7行 public static void main(String[] args) {第8行 TempTest t = new TempTest();第9行 A a = new A();第10行 a.age = 10;第11行 t.test1(a);第12行System.out.println(”main方法中的age=”+a.age);第13行 }第14行}第15行class A{第16行 public int age = 0;第17行}运行结果为:test1方法中的age=20main方法中的age=10为什么这次的运行结果和前面的例子不一样呢,还是使用内存示意图来理解一下6:再次理解按引用传递(1):运行开始,运行第9行,创建了一个A的实例,内存分配示意如下:(2):运行第10行,是修改A实例里面的age的值,运行后内存分配示意如下:(3):运行第11行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。
请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。
内存分配示意如下:由于是按引用传递,也就是传递的是内存空间的地址,所以传递完成后形成的新的内存示意图如下:也就是说:是两个变量都指向同一个空间。
(4):运行第3行,为test1方法中的变量a重新生成了新的A实例的,完成后形成的新的内存示意图如下:(5):运行第4行,为test1方法中的变量a指向的新的A实例的age进行赋值,完成后形成的新的内存示意图如下:注意:这个时候test1方法中的变量a的age被改变,而main方法中的是没有改变的。