值类型
8大数据类型
byte、boolean、char、short、int、float、long、double
只有以上所述类型才属于值类型
值类型变量存储的是内存地址中值的拷贝
值之间的传递
他们之间在传递时,会直接传入值的拷贝。
如果为其中一个变量重新赋值,并不会影响另一个变量的值。
例:
int c = 5;
int d = c;
c = 6;
//此时的d 还是5
问题:为什么不会影响?
因为 c存的是内存地址值的拷贝 ,重新赋值时会去内存地址(栈)中寻找值并复制。找不到则从内存地址创建值并复制给变量!
引用类型
除了8大数据类型以外的其他类型都是引用类型
引用类型存储的是指向对象的内存地址
引用之间的传递
引用类型传递的是对象的内存地址,并不是对象的拷贝,所以修改同一内存地址的对象内容会直接影响其他引用该对象的变量
例1:
StringBuilder a = new StringBuilder();
StringBuilder b = a;
a.append("1234");
System.out.println(b);
//1234
引用类型仅仅只是指向内存地址,当重新赋其他对象时,只会使其指向的内存地址的指针发生改变,并不会影响到原来内存地址的对象。
例2:
String a = "sdaf";
String b = a;
a = "1234";
System.out.println(b);
//sdaf
a的赋值并没有影响到b。因为a=“1234”的操作是重新创建对象的操作。仅仅只是它的引用地址发生了改变。所以b所引用的对象并没有发生任何改变自然也就等于原值了。
通过以上简述,可以看出来,不管是值传递,还是引用传递。传递的其实都是变量所储存的内容!他们实际上并没有什么本质上的区别
实参和形参
- 实参(argument)就是主调方法传入的参数。
- 形参(parameter)就是被调方法定义时声明的参数,作用域仅方法本身。
传入实参必须于形参类型一致!
这两个参数不是同一个参数!
"当调用方法时,主调方法传入实参,被调方法会立即给形参分配内存空间并将实参赋值给形参,然后执行方法相关逻辑,并在方法结束后释放形参内存资源"。
以上这段话也很好的解释了为什么值类型在传递至被调方法中,修改值并不会对原变量产生影响。正如我们上面所说的一样,他们之间在传递时,会直接复制值进行传递。
同时也解释了为什么传入引用类型时修改对象内数据会对原变量产生影响。因为传递的是内存地址
再说一点与本章内容无关的知识:值类型的值储存的地方取决于 值类型变量声明的地方。如果为类变量,那么值存在堆中。类初始化时创建。如果为成员变量,那么值存在堆中,随对象的创建而创建,为对象私有。如果为局部变量,则随方法的入栈创建在栈中,局部变量可以共享栈中的数据,随方法的出栈而销毁。
总结
- 1.值传递和引用传递 其实传递的都是其变量所存储的内容。他们本质没有什么区别
- 2.对象中有可以供你直接操作的方法或字段。操作对象的内容会直接修改所引用内存空间的对象内容。所以其他引用此对象的变量自然都会改变。
- 3.值类型并没有可以让你操作的内部元素。你只能通过重新赋值的方式改变变量所存储的值。改变的也只能是重新赋值的变量。
- 4.值类型存储的是内存地址的值的拷贝,引用类型存储的是引用对象的内存地址。两者重新赋值都不会对其原有的值造成影响。
- 5.方法会将传入的实参赋值给形参。形参作用于方法内。随方法的结束而销毁。
参考
Java虚拟机—栈帧、操作数栈和局部变量表
基本数据类型的值存放在哪里
文章包含作者个人见解,如果错误 敬请指正。
将喜欢的一切留在身边,这便是努力的意义。
菅江晖