Java中传值与传引用的三种情况

合集下载

函数调用时参数传递方式

函数调用时参数传递方式

函数调用时参数传递方式在编程语言中,函数是一段可重用的代码块,可以被其他部分调用和执行。

函数的参数是在调用函数时传递给函数的信息。

参数传递的方式不同,可以分为值传递、引用传递和指针传递。

1.值传递(传值调用):值传递是指将实际参数的值复制给形式参数,形式参数在函数内部使用时是独立的变量,对形参进行修改不会影响实参的值。

值传递适用于不需要修改实参的情况和使用简单数据类型作为参数的情况。

值传递的特点是速度相对较快,但当传递大对象时会占用较多的内存和时间。

2.引用传递(传引用调用):引用传递是指将实际参数的引用传递给形式参数,形式参数在函数内部使用时是实参的别名,对形参的修改会影响到实参的值。

引用传递适用于需要修改实参的情况和使用复杂数据类型作为参数的情况。

引用传递的特点是可以节省内存和时间,但是有可能会对实参造成不可预期的修改。

3.指针传递:指针传递是指将实际参数的指针传递给形式参数,在函数内部使用指针来访问实参的值。

指针传递适用于需要修改实参的情况和需要进行动态内存分配的情况。

指针传递的特点是可以直接通过指针修改实参的值,但是需要注意指针的合法性和空指针的处理。

不同的编程语言会有不同的参数传递方式,默认情况下,大多数编程语言采用值传递的方式。

而在一些编程语言中,也可以通过特定的语法来实现引用传递或者指针传递。

在C语言中,函数的参数传递方式是值传递。

函数参数的值会被复制到对应的形式参数中,形式参数在函数内部修改不会影响实际参数的值。

如果需要在函数内部修改实际参数,可以通过传递指针或引用的方式来实现。

在C++中,函数的参数传递方式可以通过关键字来显式地指定。

默认情况下,C++采用值传递的方式,但可以使用引用传递或指针传递来实现对实际参数的修改。

引用传递使用引用类型作为参数,可以直接对实际参数进行修改。

指针传递使用指针类型作为参数,通过指针来访问实际参数的值。

在Java中,函数的参数传递方式是值传递。

所有的参数都是按值传递,包括基本数据类型和对象引用。

Java传参的三种情况

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中的参数传递——值传递、引用传递

java中的参数传递——值传递、引用传递
这说明什么,原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为。
下一个问题:Java 应用程序有且仅有的一种参数传递机制,即按值传递
class Test03 {
public static void main(String[] args) {
StringBuffer s= new StringBuffer("good");
因此5的输出打印的是新创建的对象的内容,而6打印的原来的s的内容
7和8两个地方修改对象内容,但是9和10的输出为什么是那样的呢?
Java 应用程序有且仅有的一种参数传递机制,即按值传递。
至此,我想总结一下我对这个问题的最后的看法和我认为可以帮助大家理解的一种方法:
我们可以将java中的对象理解为c/c++中的指针
参数是按值而不是按引用传递的,说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递。
在 Java 应用程序中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。Java 应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数。参数可以是对象引用,而 Java 应用程序是按值传递对象引用的。
程序运行的输出是:
good afternoon.
这说明s2和s是同一个对象。
这里有一点要澄清的是,这里的传对象其实也是传值,因为对象就是一个指针,这个赋值是指针之间的赋值,因此在java中就将它说成了传引用。(引用是什么?不就是地址吗?地址是什么,不过就是一个整数值)
再看看下面的例子:
确实,这一点我想大家没有任何疑问,例如:
class Test01{
public static void main(String[] args){

java方法引用传递

java方法引用传递

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方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清。
(一)基本数据类型:传值,方法不会改变实参的值。
public class TestFun {
public static void testInt(int i){
i=5;
}
public static void main(String[] args) {
public class TestFun2 {
public static void testStr(String str){
str="hello";//型参指向字符串 “hello”
}
public static void main(String[] args) {
String s="1" ;
TestFun2.testStr(s);
new TestFun4().testStringBuffer(sb);
System.out.println("sb="+sb.toString());//内容变化了
}
}
执行结果,打印:sb=my java 。
所以比较参数是String和StringBuffer 的两个例子就会理解什么是“改变实参对象内容”了。
new TestFun3().testMap(map);
System.out.println("map size:"+map.size()); //map内容变化了
}
}
执行结果,打印:map size:2 。可见在方法testMap()内改变了实参的内容。
(3)第二个例子是拿map举例的,还有经常涉及的是 StringBuffer :

java 值传递与引用传递的详细理解

java 值传递与引用传递的详细理解

java 值传递与引用传递的详细理解在 Java 中,参数传递是一个非常重要的概念,不同的参数传递方式会对程序的行为产生不同的影响。

Java 中的参数传递分为值传递和引用传递两种。

其中,值传递是指将对象的引用作为参数传递给方法,方法内部对这个引用进行操作,从而改变原始对象的状态;而引用传递则是将对象本身作为参数传递给方法,方法内部对这个对象进行操作,从而改变原始对象的状态。

值传递和引用传递的本质区别在于变量存储的是对象的引用还是对象本身的值。

在 Java 中,基本类型都是值类型,即它们存储的是它们的值,当一个基本类型的对象作为参数传递给方法时,方法内部只是对这个对象的值进行操作,而不会影响到原始对象的值。

而对于引用类型,它们存储的是对象本身的地址,当一个引用类型的对象作为参数传递给方法时,方法内部只是对这个对象的地址进行操作,即改变引用的地址,那么原始对象就被覆盖了,也就是说,引用传递会导致原始对象被覆盖或者改变。

在实际的编程中,值传递和引用传递的使用要根据具体的情况来决定。

一般来说,对于基本类型,建议使用值传递,因为基本类型的值本身就包含了它们的值,没有必要再进行引用传递;而对于引用类型,建议使用引用传递,因为引用类型的对象本身就包含了对象本身的地址,引用传递可以更好地保护原始对象的状态。

Java 中的参数传递是一个非常重要的概念,不同的参数传递方式会对程序的行为产生不同的影响。

Java 中的参数传递分为值传递和引用传递两种。

值传递是指将对象的引用作为参数传递给方法,方法内部对这个引用进行操作,从而改变原始对象的状态;而引用传递则是将对象本身作为参数传递给方法,方法内部对这个对象进行操作,从而改变原始对象的状态。

值传递和引用传递的本质区别在于变量存储的是对象的引用还是对象本身的值。

JAVA传值与传引用

JAVA传值与传引用

a_ = n;
a_book.price = p;
}
public void output(){ //实例方法,输出对象信息
System.out.println("name: " + name + "\t" + "price: " + price);
}
}
public class PassAddr{
14.
}
15. }
运行结果:
[java] view plaincopyprint?
1. Hello,World!
test(string)调用了 test(StringBuffer) 方法,并将 string 作 为参数传递了进去。这里 string 是一个引用,这一点是勿庸置 疑的。前面提到,引用是一种数据类型,而且不是对象,所以 它不可能按引用传递,所以它是按值传递的,它么它的值究竟 是什么呢?是对象的地址。 由此可见,对象作为参数的时候是按值传递的,对吗? 错!为什么错,让我们看另一个例子:
8.
StringBuffer a = new
StringBuffer("Hello");
9.
StringBuffer b = a;
10.
b.append(", World");
11.
System.out.println("a is "+ a);
12.
}
13. }
运行结果:
[java] view plaincopyprint?
5. */
6. public class Test {

值类型和引用类型的区别是什么

值类型和引用类型的区别是什么

值类型和引用类型的区别是什么值类型和引用类型经常出现在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中值类型和引⽤类型的区别篇⼀ 值类型通常被分配在栈上,它的变量直接包含变量的实例,使⽤效率⽐较⾼。

java中值类型和引⽤类型的区别篇⼆ 引⽤类型分配在托管堆上,引⽤类型的变量通常包含⼀个指向实例的指针,变量通过该指针来引⽤实例。

java中值类型和引⽤类型的区别篇三 值类型继承⾃ValueType(注意:⽽System.ValueType⼜继承⾃System.Object);⽽引⽤类型继承⾃System.Object。

java中值类型和引⽤类型的区别篇四 值类型变量包含其实例数据,每个变量保存了其本⾝的数据拷⻉(副本),因此在默认情况下,值类型的参数传递不会影响参数本⾝;⽽引⽤类型变量保存了其数据的引⽤地址,因此以引⽤⽅式进⾏参数传递时会影响到参数本⾝,因为两个变量会引⽤了内存中的同⼀块地址。

java中值类型和引⽤类型的区别篇五 值类型有两种表⽰:装箱与拆箱;引⽤类型只有装箱⼀种形式。

我会在下节以专⻔的篇幅来深⼊讨论这个话题。

java中值类型和引⽤类型的区别篇六 典型的值类型为:struct,enum以及⼤量的内置值类型;⽽能称为类的都可以说是引⽤类型。

java中值类型和引⽤类型的区别篇七 值类型的内存不由GC(垃圾回收,Gabage Collection)控制,作⽤域结束时,值类型会⾃⾏释放,减少了托管堆的压⼒,因此具有性能上的优势。

例如,通常struct⽐class更⾼效;⽽引⽤类型的内存回收,由GC 来完成,微软甚⾄建议⽤户最好不要⾃⾏释放内存。

java中值类型和引⽤类型的区别篇⼋ 值类型是密封的(sealed),因此值类型不能作为其他任何类型的基类,但是可以单继承或者多继承接⼝;⽽引⽤类型⼀般都有继承性。

Java中的值传递和引用传递的区别

Java中的值传递和引用传递的区别

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集合中的传值和传引用

java集合中的传值和传引用

java集合中的传值和传引⽤
在学习java集合过程中发现了传值和传引⽤的区别:
我们来看下⾯两句话
●java集合就像⼀种容器,我们可以把多个对象(实际上是对象的引⽤),丢进该容器。

(来⾃疯狂java讲义)
●当使⽤Iterator对象集合元素进⾏迭代时,Iterator并不是把集合元素本⾝传给迭代变量,⽽是把集合元素的值传递给迭代变量。

(来⾃疯狂java讲义)
引⽤和值的影响在于,拿到引⽤的对象可以对被引⽤的元素进⾏修改,值却不可以。

使⽤传值这种⽅式的时候,必须要注意上下⽂位置。

位置不同传过来的值会不⼀样。

在这点上,⽽引⽤对象却可以随意。

//传值 itt位置1 itt对象的值为空
Set<Object> mySet = new HashSet<Object>();
Iterator<Object> itt = mySet.iterator();
mySet.add(new Object());
//传值 itt位置2 ittt对象的值等于所new的对象引⽤
Set<Object> mySet = new HashSet<Object>();
mySet.add(new Object());
Iterator<Object> itt = mySet.iterator();。

Java中传值与传引用

Java中传值与传引用

Java中传值与传引⽤不管Java参数类型是什么,⼀律传递参数的副本。

《Thinking In Java》:“When you're passing primitives into a method,you get a distinct copy of the primitive.When you're passing a reference into a method,you get a copy of the reference.(如果Java是传值,那么传递的是值的副本;如果Java是传引⽤,那么传递的是引⽤的副本)”。

在Java中,变量分为以下两类。

1. 对于基本类型变量(int, long, double, float, byte, boolean, char),Java是传值的副本。

2. 对于⼀切对象型变量,Java都是传引⽤的副本。

(如String) 对基本类型⽽⾔,传值就是把⾃⼰复制⼀份传递,即使⾃⼰的副本变了,⾃⼰也不变。

⽽对于对象类型⽽⾔,它传的引⽤副本指向⾃⼰的地址,⽽不是⾃⼰实际值的副本。

《Thinking In Java》:“不管是基本类型还是对象类型,都是传值。

”,这种说法也没有错,因为它们把引⽤副本也当做是⼀种“值”。

举⼏个栗⼦例⼀:基本数据类型 可以看出,test()⽅法并没有对test参数源产⽣影响,即对main⽅法中的test变量没有影响,说明参数类型是简单类型的时候,是按值传递的。

以参数形式传递简单类型的变量时,实际上是将参数的值作为⼀个副本传进⽅法函数的,所以在⽅法函数中不管怎么改变其值,其结果都是只改变了副本的值,⽽不是源值。

例⼆:对象类型⼀ 其中string是⼀个引⽤,Java对引⽤形式传递对象类型的变量时,实际上是将引⽤作为⼀个副本传进⽅法函数的。

⽽这个引⽤的副本所指向的就是对象的地址。

所以说,通过引⽤副本找到地址并修改地址中的值,也就修改了对象。

JAVA传参的三种情况

JAVA传参的三种情况

JAVA传参的三种情况Java中传参的方式有三种情况,分别为按值传递、按引用传递和传递对象。

1.按值传递:按值传递是指将实际参数的值复制给形式参数,即在方法调用时,实际参数的值被复制到方法的形式参数中。

这意味着,在方法中对形式参数的修改不会影响实际参数的值。

Java的基本数据类型如int、float、char等都是按值传递的。

下面是一个示例:```javapublic class Mainpublic static void main(String[] args)int num = 10;System.out.println("调用方法前的值:" + num);changeValue(num);System.out.println("调用方法后的值:" + num);}public static void changeValue(int value)value = 20;System.out.println("方法中的值:" + value);}```上述代码输出结果为:```调用方法前的值:10方法中的值:20调用方法后的值:10```从结果可以看出,在方法中修改形式参数的值,并不会影响实际参数的值。

2.按引用传递:按引用传递是指将实际参数的引用复制给形式参数,即在方法调用时,实际参数的引用被复制到方法的形式参数中。

这意味着,在方法中对形式参数的修改会改变实际参数的值。

Java中的非基本数据类型如数组、对象等都是按引用传递的。

下面是一个示例:```javapublic class Mainpublic static void main(String[] args)int[] arr = {1, 2, 3};System.out.println("调用方法前的数组:" +Arrays.toString(arr));changeArray(arr);System.out.println("调用方法后的数组:" +Arrays.toString(arr));}public static void changeArray(int[] array)array[0] = 4;System.out.println("方法中的数组:" +Arrays.toString(array));}```上述代码输出结果为:```调用方法前的数组:[1,2,3]方法中的数组:[4,2,3]调用方法后的数组:[4,2,3]```从结果可以看出,在方法中修改形式参数所引用的数组的值,实际参数的值也会随之改变。

java值传递和引用传递的实例

java值传递和引用传递的实例

Java值传递和引用传递的实例引言在Java编程中,传递参数是一项基本的操作。

了解参数传递的方式对于理解Java 程序的执行过程至关重要。

Java中有两种传递参数的方式:值传递和引用传递。

本文将通过实例来详细讨论这两种传递方式的特点和区别。

值传递值传递是指将实参的值复制一份传递给形参,在方法内部对形参的修改不会影响实参的值。

下面通过一个例子来说明值传递的特点。

例子1:基本数据类型的值传递public class ValuePassingExample {public static void main(String[] args) {int num = 10;System.out.println("调用方法前,num的值为:" + num);modifyValue(num);System.out.println("调用方法后,num的值为:" + num);}public static void modifyValue(int value) {value = 20;System.out.println("方法内部修改后,value的值为:" + value);}}输出结果:调用方法前,num的值为:10方法内部修改后,value的值为:20调用方法后,num的值为:10从输出结果可以看出,虽然在方法内部修改了形参value的值,但是对实参num没有任何影响。

这是因为值传递是将实参的值复制给形参,形参和实参是两个独立的变量。

例子2:String类的值传递public class ValuePassingExample {public static void main(String[] args) {String str = "Hello";System.out.println("调用方法前,str的值为:" + str);modifyValue(str);System.out.println("调用方法后,str的值为:" + str);}public static void modifyValue(String value) {value = "World";System.out.println("方法内部修改后,value的值为:" + value);}}输出结果:调用方法前,str的值为:Hello方法内部修改后,value的值为:World调用方法后,str的值为:Hello同样地,对于String类型的参数,值传递也不会改变实参的值。

Java:详解传值和传引用

Java:详解传值和传引用

Java:详解传值和传引⽤传值和传引⽤When you’re passing primitives into a method ,you get a distinct copy of the primitive. When you’re passing a reference into amethod , you get a copy of the reference.以上引⾃《Thinging in Java》,总结⼀下就是不管Java参数的类型是什么,⼀律传递参数的副本。

在Java中,变量分为以下两类:1. 对于基本类型变量(int、long、double、float、byte、boolean、char),Java是传值的副本。

2. 对于⼀切对象型变量,Java都是传引⽤的副本,其实穿引⽤副本的实质就是复制指向地址的指针。

⼀、传值例1:传Int类型的值程序{% highlight java linenos %}@Testpublic void passInt(){int testInt = 0;System.out.println(“Before operation, testInt is : ” + testInt);intOperation(testInt);System.out.println(“After operation, testInt is : ” + testInt);}public void intOperation(int i){i = 5;System.out.println("In operation, testInt is : " + i);}{% endhighlight %}结果{% highlight java linenos %}Before operation, testInt is : 0In operation, testInt is : 5After operation, testInt is : 0{% endhighlight %}总结结果不难看出来,虽说intOperation()⽅法改变了传进来的参数值,但对这个参数源本⾝并没有影响,参数类型是简单类型的时候,是按值传递的。

java关于传值与传引用

java关于传值与传引用

java关于传值与传引⽤关于java传值还是传引⽤的问题经常出现在⼀些烦⼈的⾯试题中,主要考察个⼈对java基础的掌握情况。

⾸先明确⼀下:本地⽅法中,java的参数传递都是传值。

但是如果是远程调⽤⽅法时,会将对象本⾝传递过去Java是本地编程多是传值,这个值包括基本值和引⽤值,分别对应基本类型和引⽤类型。

基本类型就不说了。

引⽤类型虽然是传值,但是却表现出传引⽤的效果。

传递过去的对象如果被改变,也会导致调⽤对象中值变化。

因此,编写库⽂件时要遵循⼀点:不要去改变传⼊值,使⽤内部对象接收内容,然后对内部对象进⾏操作在返回结果。

先看⼀下 Object obj = new Object();过程中栈和堆中做了哪些事情。

反编译出来内容如下Code:0: new #2 // class java/lang/Object3: dup4: invokespecial #1 // Method java/lang/Object."<init>":()V7: astore_1new:创建⼀个Object对象并将其引⽤进栈dup:复制栈顶值invokespecial:执⾏Object对象的构造函数进⾏初始化astore:将复制的栈顶值赋值给obj中,并将栈顶值出栈从上可知,obj中存放着Object对象的引⽤,为引⽤值。

当obj作为参数传递时将引⽤值传递给另外⼀个引⽤obj1,此时obj1 就指向了堆中的对象Object。

此时看起来像是传递了引⽤过去,实际上是专递了obj中的Object对象引⽤的值.但是如果直接对obj1进⾏操作的话,也就等于在操作obj引⽤的对象,导致obj引⽤内容的改变。

特别的,关于空引⽤null,null可以是任何引⽤类型的特殊值,但是基本类型不可以为null。

java函数参数传递方式

java函数参数传递方式

java函数参数传递方式
在Java中,函数参数传递方式有两种:值传递和引用传递。

一、值传递
值传递是指在函数调用时,将实际参数的值传递给形式参数,此时实际参数的值不会受到形式参数的影响。

在函数内部修改形式参数的值并不影响实际参数的值,因为形式参数和实际参数是两个不同的变量,它们所占用的内存空间也不同。

例如:
以上代码中,swap函数并没有改变实际参数a和b的值,输出结果为a=10,b=20。

因为在函数swap中,形式参数x和y是两个新的变量,它们的值是由实际参数a和b复制而来的,因此在函数swap中交换x和y的值不会对a和b产生任何影响。

二、引用传递
以上代码中,change函数通过引用传递修改了实际参数arr的值,输出结果为[2, 4, 6]。

因为在函数change中,形式参数arr和实际参数arr指向同一个数组对象,函数change对形式参数arr的操作将直接影响到实际参数arr。

三、小结
引用传递是指将实际参数的地址传递给形式参数,形式参数和实际参数指向同一个对象,对形式参数的操作将影响到实际参数。

java值传递和引用传递的实例

java值传递和引用传递的实例

java值传递和引用传递的实例摘要:一、值传递和引用传递的定义与区别二、值传递的实例三、引用传递的实例四、总结正文:一、值传递和引用传递的定义与区别在Java 编程中,我们经常会遇到值传递和引用传递这两种参数传递方式。

值传递是指在方法调用时,实参的值被复制一份传递给形参,方法内对参数值的改变并不会影响实参。

而引用传递是指在方法调用时,实参的地址(即对象的引用)被传递给形参,方法内对参数值的改变会直接影响实参。

二、值传递的实例以一个简单的实例来说明值传递。

我们有一个名为`Person`的类,其中有一个`String`类型的成员变量`name`。

我们定义了一个`changeName`方法,接收一个`String`类型的参数`newName`,用于改变`name`的值。

```javapublic class Person {private String name;public Person(String name) { = name;public void changeName(String newName) { = newName;}}```在这个例子中,当我们调用`changeName`方法时,实参`newName`的值被复制一份传递给形参`name`。

因此在方法内对`name`的修改并不会影响实参`newName`的值。

三、引用传递的实例接下来,我们通过一个实例来说明引用传递。

我们定义了一个`changeValue`方法,接收一个`Integer`类型的参数`newValue`,用于改变`value`的值。

注意,这里我们传递的是`Integer`类型的对象,而不是基本类型的值。

```javapublic class Person {private Integer value;public Person(Integer value) {this.value = value;}public void changeValue(Integer newValue) {this.value = newValue;}```在这个例子中,当我们调用`changeValue`方法时,实参`newValue`的地址(即对象的引用)被传递给形参`value`。

Java——值传递和引用传递

Java——值传递和引用传递

Java——值传递和引⽤传递值传递在⽅法被调⽤时,实参通过形参把它的内容副本传⼊⽅法内部,此时形参接收到的内容是实参值的⼀个拷贝,因此在⽅法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。

先来看个例⼦:public static void valueCross(int age,float weight) {System.out.println("传⼊的age值:"+age);System.out.println("传⼊的weight值:"+weight);age=23;weight=60;System.out.println("修改后的age值:"+age);System.out.println("修改后的weight值:"+weight);}public static void main(String[] args) {int age=10;int weight=50;valueCross(age,weight);System.out.println("⽅法执⾏后的age:"+age);System.out.println("⽅法执⾏后的weight:"+weight);}运⾏结果:传⼊的age值:10传⼊的weight值:50.0修改后的age值:23修改后的weight值:60.0⽅法执⾏后的age:10⽅法执⾏后的weight:50我们可以看到valueCross⽅法执⾏后,实参age和weight的值并没有发⽣变化,这是什么原因?⾸先程序运⾏时,先从main⽅法开始执⾏,此时JVM为main()⽅法往虚拟机栈中压⼊⼀个栈帧,即为当前栈帧,⽤来存放main()中的局部变量表(包括参数)、操作栈、⽅法出⼝等信息,如a和w都是mian()⽅法中的局部变量,因此可以断定,age和weight是躺着mian⽅法所在的栈帧中接着调⽤valueCross⽅法,此时JVM为valueCross()⽅法往虚拟机中压⼊⼀个栈帧,即为当前栈帧,⽤于存放valueCross⽅法的局部变量等信息;因此age和weight是躺着valueCrossTest⽅法所在的栈帧中,⽽他们的值是从a和w的值copy了⼀份副本⽽得,如图:因此这两个age和weight对应的内容不是同⼀个,在valueCross⽅法中修改的只是⾃⼰栈中的内容,并没有修改main⽅法栈中的内容引⽤传递”引⽤”也就是指向真实内容的地址值,在⽅法调⽤时,实参的地址通过⽅法调⽤被传递给相应的形参,在⽅法体内,形参和实参指向同⼀块内存地址,对形参的操作会影响的真实内容。

值传递在Java中

值传递在Java中

值传递在Java中在程序设计中,值传递(Pass by Value)和引用传递(Pass by Reference)是两种不同的参数传递方式。

在Java中,作为一种面向对象的编程语言,值传递在很多场景中起到了重要的作用。

本文将探讨值传递在Java中的概念、使用方式和一些注意事项。

一、概念值传递是指在方法调用时,将实际参数的值复制给形式参数,实际参数的改变不会影响到形式参数的值。

Java中的基本类型(int、float、boolean等)都是以值传递的方式进行参数传递。

二、基本类型的值传递1. 基本类型的值传递基本类型在值传递过程中,会将实际参数的值复制一份给形式参数,即在方法内部操作的是参数的副本,不会改变原始值。

```javapublic class ValuePassingExample {public static void main(String[] args) {int num1 = 10;System.out.println("Before method call, num1 = " + num1);changeValue(num1);}public static void changeValue(int num) {num = 20;}}```输出结果:```Before method call, num1 = 10After method call, num1 = 10```2. 基本类型数组的值传递基本类型数组作为参数传递时,同样是值传递的方式。

在方法内部操作数组的元素值时,不会改变原始数组的值。

```javapublic class ArrayPassingExample {public static void main(String[] args) {int[] numbers = {1, 2, 3, 4, 5};numbers[0]);changeArrayValue(numbers);System.out.println("After method call, numbers[0] = " + numbers[0]);}public static void changeArrayValue(int[] arr) {arr[0] = 10;}}```输出结果:```Before method call, numbers[0] = 1After method call, numbers[0] = 10```三、对象类型的值传递1. 对象类型的值传递在Java中,对象类型包括类、接口和数组。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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方法中的是没有改变的。

相关文档
最新文档