java中各种数据类型是怎么存放在内存的?

内存区域

java把内存分两种:一种是栈内存,另一种是堆内存

  1. 在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
  2. 堆内存用来存放由new创建的对象和数组以及对象的实例变量。在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理。

堆和栈的优缺点

  1. 堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。
  2. 缺点就是要在运行时动态分配内存,存取速度较慢;
  3. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。另外,栈数据可以共享。
  4. 但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

基本数据类型存储

如果是在方法中定义基本类型,这是算局部变量,会存在栈中。如果是在类中定义的基本类型属性(实例域),就是放在对象中,也就是堆中。

以方法中定义的基本类型为例

int a=3;
int b=3;

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b这个引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

定义完a与b的值后,再令a = 4;那么,b不会等于4,还是等于3。在编译器内部,遇到时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

对象存储

用Rectangle rect;声明一个对象rect时,将在栈内存为对象的引用变量rect分配内存空间,但Rectangle的值为空,称rect是一个空对象。空对象不能使用,因为它还没有引用任何”实体”。

当执行rect=new Rectangle(3,5);时,就会在堆中存对象。会做两件事:在堆内存中为类的成员变量width,height分配内存,并将其初始化为各数据类型的默认值;接着进行显式初始化(类定义时的初始化值);最后调用构造方法,为成员变量赋值。返回堆内存中对象的引用(相当于首地址)给引用变量rect,以后就可以通过rect来引用堆内存中的对象了。

注意:包装类也是对象,所以也是存在堆中。

String

String也是对象,但它比较特别。

这个涉及到JVM的知识,具体是因为运行时常量池。参考:
https://blog.csdn.net/weixin_43751710/article/details/105394507

主要是因为String在创建时,会在运行时常量池中存一份。我们创建String时,大概有如下三种方法。

String s1 = "abc";
String s2 = new String("abc");
String s3 = new String("abc").intern();

对于第一种:String s1 = “abc”;,直接在运行时常量池中创建一个"abc",s1指向它。
对于第二种:String s2 = new String(“abc”);,如果常量池中没有"abc",则在常量池中创建一个,然后再堆中创建一个String对象,指向常量池中的"abc"。
对于第三种:String s3 = new String(“abc”).intern();,如果常量池中没有"abc",则在常量池中创建一个,然后将常量池中对于"abc"的引用返回。

也就是说:

s1 == s3//结果为true
s1 == s2//结果为false

https://www.cnblogs.com/xiohao/p/4278173.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值