文章目录

  • JVM内存区域的组成
  • 基本类型和引用类型:
  • 数据类型存储细节


JVM内存区域的组成


想要弄懂基本类型与引用类型以及他们的存储,就要先知道java中内存区域分为什么:

1)【内存区域的划分】

1、栈内存

在函数中定义的基本类型变量(即基本类型的局部变量 int a;中的a变量)和对象的引用变量(即对象的变量名Person p;中的p)都在函数的栈内存中分配;

2、堆内存

堆内存用来存放由new创建的对象和数组以及对象的实例变量(即全局变量)(堆中不存放基本类型和对象引用,只存放对象本身 )

其中对象的引用类型做如下解释:

java 声明引用类型变量 是否开辟内存空间 java引用变量占多大内存_java

基本类型和引用类型:

1、基本类型

基本类型可以分为8种:

byte、short、int、long、float、double、char、boolean

存放在栈空间中,未初始化时为随机值

2、引用类型

引用类型可以分为:

1)类class引用

String、Date、Byte、 Short 、Integer 、Long 、Float、Double 、Character 、Boolean等

2)接口interface引用

List、remove()、Map<K,V>等

3)数组引用

int[] t = new int[5];

存放在堆空间中,未初始化时有默认的值。Integer默认为null,且引用类型默认值都为null,基本类型整型为0,浮点型是0.0,布尔型是false,char为 ‘/uoooo’

java 声明引用类型变量 是否开辟内存空间 java引用变量占多大内存_java_02

数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false;
数组一旦创建后,大小就不可改变

@@@注意不要搞混:
我们说

String a = new String();

代码中引用类型时String,a是引用类型的变量,a指向引用类型String。
此时:a存储在栈中,String()是在堆中

数据类型存储细节

1)基本数据类型
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。

java 声明引用类型变量 是否开辟内存空间 java引用变量占多大内存_java_03

   编译器先处理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的值。

2) String

String是一个特殊的包装类数据。可以用以下两种方式创建:`String d = new String(“abc”);String d = “abc”;

第一种创建方式,和普通对象的的创建过程一样;

第二种创建方式,java内部将此语句转化为以下几个步骤:

(1)先定义一个名为d的对String类的对象引用变量:String d;

(2)在栈中查找有没有存放值为”abc”的地址,如果没有,则开辟一个存放字面值为”abc” 地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈 这个地址旁边记下这个引用的对象e。如果已经有了值为”abc”的地址,则查找对象o,并 回o的地址。

(3)将a指向对象o的地址。 值得注意的是,一般String类中字符串值都是直接存值的。但像String a = “abc”;这种情况下,其字符串值却是保存了一个指向存在栈中数据的引用。 为了更好地说明这个问题。

String a="abc";
String b="abc";//和int情况一样,也会找字面值等于abc的地址
System.out.println(a==b);//true