基本类型
基本类型
特性 | bit | default | 备注 | |
---|---|---|---|---|
byte | 整型,补码 | 8 | 0 | |
short | 整型,补码 | 16 | 0 | |
int | 整型,补码 | 32 | 0 | |
long | 整型,补码 | 64 | 0L | 必须有L后缀 |
float | 浮点型,IEEE 754 | 32 | 0.0f | 必须有f后缀 |
double | 浮点型,IEEE 754 | 64 | 0.0d | 可不加d后缀 |
char | 字符型,Unicode | 16 | ‘\u0000’ | |
boolean | 布尔型 | 1 | false | |
void |
包装类
上面8个基本数据类型均有对应的包装类,数字类全部继承于抽象类Number
。Boolean
和Character
未继承任何类,实现Serializble
,Compareable
,Constable
接口Number
实现Serializble
接口,其子类均实现Compareable
,Constable
接口,除Byte
和Short
类外,Number
子类还实现了ConstantDesc
接口。
包装类是引用类型,默认值为null
装箱与拆箱
基本类型与对应的包装类对象之间,来回转换的过程称为装箱与拆箱。Java将这个过程自动化,即实现自动装箱与自动拆箱。
Integer i = 20; // 自动装箱,实际执行Integer.valueOf(20);
int j = i; // 自动拆箱,实际执行 int j = i.intValue();
缓存
在每一个整型包装类以及字符型包装类Character
中,都实现了一个对应Cache
缓存类,在类加载的时候,会自动缓存一定数量的包装类对象。
当调用静态方法.valueOf()
,若值在缓存区间内,则直接返回对应的包装类对象,不在则新建一个包装类对象,新对象不缓存
Byte
,Short
,Long
,会缓存值为-128~127
的包装类对象Character
缓存对应值为0~127
的包装类对象Integer
类型缓存起始值为-128
,通过配置VM参数java.lang.Integer.IntegerCache.high
确定缓存上界 ```java Integer i = 100000; Integer j = 100000; System.out.println(i == j); // 结果为fasle Integer p = 100; Integer q = 100; System.out.println(p == q); //因为在缓存范围内,指向同一个对象,结果为true
q = q + 1; //实际调用方式,其中q.intValue()返回值为 int // q = Integer.valueOf(q.intValue() + 1)
:::danger
❗`==`与`equals`<br />在以上这些包装类以及`String`类型中,`==` 在比较时,比较的是地址,而`equals`则比较的是值<br />因此当比较两个不同包装类对象时,因为对象地址不同,使用`==`得到的结果也会是`false`<br />`equals`方法则将比较双方的实际值取出再进行`==`比较,得到结果即为预期的`true`
:::
<a name="smRyK"></a>
### 引用类型
**Java中类型可分为两大类:基本类型与引用类型。**除int,double等基本数据类型外,其余一切类型均为引用类型,均继承自Object类。引用类似于C语言中的指针。
<a name="emcaB"></a>
#### Java内存分配模型
一个Java程序是一个Java进程,每个Java进程都对应着一个JVM<br />JVM的内存模型如下<br />![](https://cdn.nlark.com/yuque/0/2022/jpeg/1419739/1653574701865-035e1414-1495-444b-b584-52f311a5ea03.jpeg)
<a name="N83yo"></a>
#### 数据类型空间分配
将上图中的虚拟机栈与堆区抽离出来,来讨论在为不同的数据类型分配空间时的策略。<br />![](https://cdn.nlark.com/yuque/0/2022/jpeg/1419739/1653575598036-83eeb7cf-1ac6-4784-be86-db71e7d97c45.jpeg)<br />对于基础数据类型,会直接分配到对应的栈帧中,与堆区无关
```java
public void test() {
int s = 1;
}
public static void main(String[] args){
test();
}
而对于引用类型,则涉及堆区内存分配。其中,引用变量存储在栈区,而新建的对象则存储在堆区,当引用变量没有指向任何对象时,默认指向null
测试——演示文档
Java引用与C指针
使用上其实很类似,Java引用其底层实现也就是指针,不过Java的引用方式也更符合人的心智(至少我是这么觉得的😄。
Java, make a reference point to another reference——StackOverflow
在C中,指针自由度很高,可以得到指向指针的指针。但是在Java中,引用的处理是自动的,在作为参数去传递时,传递的是引用变量所存储的地址值。(Java强引用)