java传值调用是什么?java中的值传递和引用传递到底有什么区别
大家好,关于java传值调用是什么很多朋友都还不太明白,今天小编就来为大家分享关于java中的值传递和引用传递到底有什么区别的知识,希望对各位有所帮助!
java中参数传递,按引用传递
Java提供两种不同的类型:引用类型和原始类型(或内置类型)。另外,Java还为每个原始类型提供了封装类(Wrapper)。如果需要一个整型变量,是使用基本的 int型呢,还是使用 Integer类的一个对象呢?如果需要声明一个布尔类型,是使用基本的 boolean,还是使用 Boolean类的一个对象呢?本文可帮助您作出决定。
下表列出了原始类型以及它们的对象封装类。
原始类型封装类
=================
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
引用类型和原始类型的行为完全不同,并且它们具有不同的语义。例如,假定一个方法中有两个局部变量,一个变量为 int原始类型,另一个变量是对一个 Integer对象的对象引用:
int i= 5;//原始类型
Integer j= new Integer(10);//对象引用
这两个变量都存储在局部变量表中,并且都是在 Java操作数堆栈中操作的,但对它们的表示却完全不同。(本文中以下部分将用通用术语堆栈代替操作数堆栈或局部变量表。)原始类型 int和对象引用各占堆栈的 32位。(要表示一个 int或一个对象引用,Java虚拟机实现至少需要使用 32位存储。)Integer对象的堆栈项并不是对象本身,而是一个对象引用。
Java中的所有对象都要通过对象引用访问。对象引用是指向对象存储所在堆中的某个区域的指针。当声明一个原始类型时,就为类型本身声明了存储。前面的两行代码表示如下:
引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。
许多程序的代码将同时包含原始类型以及它们的对象封装。当检查它们是否相等时,同时使用这两种类型并了解它们如何正确相互作用和共存将成为问题。程序员必须了解这两种类型是如何工作和相互作用的,以避免代码出错。
例如,不能对原始类型调用方法,但可以对对象调用方法:
int j= 5;
j.hashCode();//错误
//...
Integer i= new Integer(5);
i.hashCode();//正确
使用原始类型无须调用 new,也无须创建对象。这节省了时间和空间。混合使用原始类型和对象也可能导致与赋值有关的意外结果。看起来没有错误的代码可能无法完成您希望做的工作。例如:
import java.awt.Point;
class Assign
{
public static void main(String args[])
{
int a= 1;
int b= 2;
Point x= new Point(0,0);
Point y= new Point(1,1);//1
System.out.println("a is"+ a);
System.out.println("b is"+ b);
System.out.println("x is"+ x);
System.out.println("y is"+ y);
System.out.println("Performing assignment and"+
"setLocation...");
a= b;
a++;
x= y;//2
x.setLocation(5,5);//3
System.out.println("a is"+a);
System.out.println("b is"+b);
System.out.println("x is"+x);
System.out.println("y is"+y);
}
}
这段代码生成以下输出:
a is 1
b is 2
x is java.awt.Point[x=0,y=0]
y is java.awt.Point[x=1,y=1]
Performing assignment and setLocation...
a is 3
b is 2
x is java.awt.Point[x=5,y=5]
y is java.awt.Point[x=5,y=5]
修改整数 a和 b的结果没什么意外的地方。b的值被赋予整型变量 a,结果 a的值增加了 1。这一输出反映了我们希望发生的情况。但是,令人感到意外的,是在赋值并调用 setLocation之后 x和 y对象的输出。我们在完成 x= y赋值之后特意对 x调用了 setLocation,x和 y的值怎么会相同呢?我们毕竟将 y赋予 x,然后更改了 x,这与我们对整数 a和 b进行的操作没什么不同。
这种混淆是由原始类型和对象的使用造成的。赋值对这两种类型所起的作用没什么不同。但它可能看起来所有不同。赋值使等号(=)左边的值等于右边的值。这一点对于原始类型(如前面的 int a和 b)是显而易见的。对于非原始类型(如 Point对象),赋值修改的是对象引用,而不是对象本身。因此,在语句
x= y;
之后,x等于 y。换句话说,因为 x和 y是对象引用,它们现在引用同一个对象。因此,对 x所作的任何更改也会更改 y。下面是//1处的代码执行以后的情况:
执行//2处的赋值以后情况如下:
当在//3处调用 setLocation时,这一方法是对 x引用的对象执行的。因为 x引用的 Point对象也正是 y所引用的对象,所以我们现在得到以下结果:
因为 x和 y引用同一个对象,所以对 x执行的所有方法与对 y执行的方法都作用于同一个对象。
区分引用类型和原始类型并理解引用的语义是很重要的。若做不到这一点,则会使编写的代码无法完成预定工作。
java中的值传递和引用传递到底有什么区别
java中在参数传递时有2种方式,两者的区别:
1、按值传递:值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。简单来说就是直接复制了一份数据过去,因为是直接复制,所以这种方式在传递时如果数据量非常大的话,运行效率自然就变低了,所以java在传递数据量很小的数据是值传递,比如java中的各种基本类型:int,float,double,boolean等类型的,具体可以自己测试。
结果:
2、按引用传递:引用传递其实就弥补了上面说的不足,如果每次传参数的时候都复制一份的话,如果这个参数占用的内存空间太大的话,运行效率会很底下,所以引用传递就是直接把内存地址传过去,也就是说引用传递时,操作的其实都是源数据,这样的话修改有时候会冲突,记得用逻辑弥补下就好了,具体的数据类型就比较多了,比如Object,二维数组,List,Map等除了基本类型的参数都是引用传递。代码:
有些文章中写的是java中所有的传参方式都是按值传递,这也说得通,无非就是文字游戏,因为无论是按值传递还是按引用传递都是把值传递过去了,所以就叫按值传递。
在java中什么是参数传递机制
参数传递,就是方法调用过程中,调用者将参数传递给被调用者的过程。
其实Java中的所有参数传递,传递的都是一样的,参数直接引用值的复制体。
1.只是对于Java基础类型(int、long、float等等),参数的引用里面包含的就是它们的值,因此是值传递,在被调用的方法内改变它们的值,不会影响调用者。
2.对于其他对象,引用里面包含的实际是参数对象的地址,也叫引用传递,在被调用的方法内改变它们的值,当然会影响调用者。
3.对于像String这样的不变类,参数传递的过程中,与第2点类似,是引用传递;但是当被调方法修改不变类的值的时候,其实是新建了一个另外的对象,那么当然也不会影响被调用者。
这里面的区别就在于,对于基础类型,Java的存储方式是引用-》值,对于其他对象,Java的存储方式是引用-》地址-》值(其中的值可能是基础类型或其他对象)。
Java中的形参和实参的区别以及传值调用和传
1.形参:用来接收调用该方法时传递的参数。只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间。因此仅仅在方法内有效。
2.实参:传递给被调用方法的值,预先创建并赋予确定值。
3.传值调用:传值调用中传递的参数为基本数据类型,参数视为形参。
4.传引用调用:传引用调用中,如果传递的参数是引用数据类型,参数视为实参。在调用的过程中,将实参的地址传递给了形参,形参上的改变都发生在实参上。
案例分析:
1.基础数据类型(传值调用)
传值,方法不会改变实参的值。
2.引用数据类型(引用调用)
传引用,方法体内改变形参引用,不会改变实参的引用,但有可能改变实参对象的属性值。
举两个例子:
(1)方法体内改变形参引用,但不会改变实参引用,实参值不变。
publicclassTestFun2{
publicstaticvoidtestStr(Stringstr){
str="hello";//型参指向字符串“hello”
}
publicstaticvoidmain(String[]args){
Strings="1";
TestFun2.testStr(s);
System.out.println("s="+s);//实参s引用没变,值也不变
}
}
执行结果打印:s=1
(2)方法体内,通过引用改变了实际参数对象的内容,注意是“内容”,引用还是不变的。
publicclassTestFun4{
publicstaticvoidtestStringBuffer(StringBuffersb){
sb.append("java");//改变了实参的内容
}
publicstaticvoidmain(String[]args){
StringBuffersb=newStringBuffer("my");
newTestFun4().testStringBuffer(sb);
System.out.println("sb="+sb.toString());//内容变化了
}
}
执行结果,打印:sb=my java。
所以比较参数是String和StringBuffer的两个例子就会理解什么是“改变实参对象内容”了。
1.java的基本数据类型是传值调用,对象引用类型是传引用。
2.当传值调用时,改变的是形参的值,并没有改变实参的值,实参的值可以传递给形参,但是,这个传递是单向的,形参不能传递回实参。
3.当引用调用时,如果参数是对象,无论对对象做了何种操作,都不会改变实参对象的引用,但是如果改变了对象的内容,就会改变实参对象的内容。
文章分享结束,java传值调用是什么和java中的值传递和引用传递到底有什么区别的答案你都知道了吗?欢迎再次光临本站哦!