Java中的值传递和引用传递
看了很多关于Java中的值传递和引用传递,我觉得有所收获,但是还是觉得有些迷惑,下面是关于我自己对于Java中的值传递和引用传递的理解。【作为一个Java初学者的理解,下面的文章可能不对,请谨慎甄别和选择,也欢迎大家来提出意见】
Java中的数据类型
众所周知,Java中的数据类型分为两大类:基本数据类型和引用数据类型,在这里就不列举分别有哪些了。
基本数据类型
比如我们定义一个基本数据类型:
int x = 10;
x = 100;
这里第一行的x
表示的是一块内存,其大小为4个字节,存储的是int
类型的数据,不妨设这块内存的起始地址为0x1111
,这块内存中的值是10
。更为形象的说,可以将x
视为起始地址为0x1111
的这块内存。
第二行代码就可以看出x = 100
,而其具体是怎么做到的呢?就是将100
这个值赋值到名为x
的这块内存中,也就是赋值到0x1111
这块内存上。
引用数据类型
我们定义一个引用数据类型
public static void main(String[] args) {
Person p1 = new Person("Alice", 10);
p1 = new Person("Bob", 20);
}
class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
main
方法中,一开始的p1
是在内存中申请了一块内存,其大小为一个Person
类的大小,存储的是Person
类型的数据,内容有Alice, 10
等信息,这块内存的起始地址不妨假设为0x2222
。那么其实和基本数据类型一样的是,p1
的含义就是这个已经实例化的对象的起始地址,也就是p1
就是0x2222
的这块内存。
紧接着p1 = new Person("Bob", 20);
,这就是再次申请了一块内存,而这块内存中存储的就是Bob, 20
等信息,假设这块内存的起始地址是0x3333
,然后将p1
的含义改为0x3333
,也就是说p1
变为了0x3333
的这块内存。
当然,真正的JVM处理可能并不会将p1
直接改为地址,也许是其他的操作,但是其本质上的意思就是上面的情况。
基本数据类型与引用数据类型的相同与不同
相同点:
- 变量名都是对应的数据地址。
不同点:
- 基本数据类型赋值时:是将值直接复制到与变量名对应的内存中去;
- 引用数据类型赋值时:是将变量名改为数据的起始地址。
接着分析传参的问题。
Java中的方法传参
Java中传递的参数有两种数据类型,一种是基本数据类型,另一种就是引用数据类型。因此就有两种传参规则:
- 基本数据类型:值传递;
- 引用数据类型:引用传递;
具体来说什么是值传递,什么是引用传递。
- 值传递:将实参复制到形参中,因此,在方法中的形参的改动,并不会对调用者的实参的改变;
- 引用传递:将实参的地址复制到形参中,因此,如果直接对形参进行改变,其本质也并不会对实参进行改变。但是如果对形参中的二级地址进行改变,则会改变实参。
这也就是为什么有些人会说,在Java中其实并没有引用传递,都是值传递的原因,其实他们说的也是对的,因为本质上来说都是值传递,只不过一个是数据本身的值传递,另一个是数据的地址的值传递而已。
在这里就不详细介绍值传递的问题了,直接说引用传递。
Java中的引用传递
上一节说的引用传递可能描述的并不是很好理解,举个例子来说:
public static void main(String[] args) {
Person p1 = new Person("Alice", 10);
System.out.println(p1);
Person.change1(p1);
System.out.println(p1);
Person.change2(p1);
System.out.println(p1);
}
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public static void change1(Person p) {
p = new Person("Bob", 20);
}
public static void change2(Person p) {
p.age = 70;
}
}
从上面代码进行分析:
change1
和change2
传进来的都是Person
类,都是属于引用传递,那么为什么change1
没有影响main
函数中的p1
,而change2
却改变了main
函数中的p1
呢?
根据Java的引用传递规则来看:
- 分析
change1
:传进来的形参p
是Alice, 10
这样的内存的地址的值0x4444
,而直接对p = new Person("Bob", 20);
这样的操作,只是将形参p
的值改为了Bob, 20
这样的内存的地址的值0x5555
,由于Java的引用传递的规则来看,这并不会影响mian
中的p1
的值还是等于0x4444
; - 分析
change2
:传进来的形参p
是Alice, 10
这样的内存的地址的值0x4444
,紧接着,对0x4444
这块内存中的age
部分内存进行了修改,而这块内存也还是在main
中的p1
所对应的内存中,因此,会对main
中的p1
进行影响。
总结
值传递和引用传递其本身都是对值的复制,不同的是,一个是数据本身的值复制,一个是数据的地址的值复制。
原文地址:https://blog.csdn.net/renshy5/article/details/135578275
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_57553.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!