基本类型

基本类型


特性 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

包装类

数据类型 - 图1上面8个基本数据类型均有对应的包装类,数字类全部继承于抽象类Number
BooleanCharacter未继承任何类,实现SerializbleCompareableConstable接口
Number实现Serializble接口,其子类均实现CompareableConstable接口,除ByteShort类外,Number子类还实现了ConstantDesc接口。
包装类是引用类型,默认值为null

装箱与拆箱

基本类型与对应的包装类对象之间,来回转换的过程称为装箱与拆箱。Java将这个过程自动化,即实现自动装箱与自动拆箱。

  1. Integer i = 20; // 自动装箱,实际执行Integer.valueOf(20);
  2. int j = i; // 自动拆箱,实际执行 int j = i.intValue();

缓存

在每一个整型包装类以及字符型包装类Character中,都实现了一个对应Cache缓存类,在类加载的时候,会自动缓存一定数量的包装类对象。
当调用静态方法.valueOf(),若值在缓存区间内,则直接返回对应的包装类对象,不在则新建一个包装类对象,新对象不缓存

  • ByteShortLong,会缓存值为-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)

  1. :::danger
  2. `==``equals`<br />在以上这些包装类以及`String`类型中,`==` 在比较时,比较的是地址,而`equals`则比较的是值<br />因此当比较两个不同包装类对象时,因为对象地址不同,使用`==`得到的结果也会是`false`<br />`equals`方法则将比较双方的实际值取出再进行`==`比较,得到结果即为预期的`true`
  3. :::
  4. <a name="smRyK"></a>
  5. ### 引用类型
  6. **Java中类型可分为两大类:基本类型与引用类型。**除intdouble等基本数据类型外,其余一切类型均为引用类型,均继承自Object类。引用类似于C语言中的指针。
  7. <a name="emcaB"></a>
  8. #### Java内存分配模型
  9. 一个Java程序是一个Java进程,每个Java进程都对应着一个JVM<br />JVM的内存模型如下<br />![](https://cdn.nlark.com/yuque/0/2022/jpeg/1419739/1653574701865-035e1414-1495-444b-b584-52f311a5ea03.jpeg)
  10. <a name="N83yo"></a>
  11. #### 数据类型空间分配
  12. 将上图中的虚拟机栈与堆区抽离出来,来讨论在为不同的数据类型分配空间时的策略。<br />![](https://cdn.nlark.com/yuque/0/2022/jpeg/1419739/1653575598036-83eeb7cf-1ac6-4784-be86-db71e7d97c45.jpeg)<br />对于基础数据类型,会直接分配到对应的栈帧中,与堆区无关
  13. ```java
  14. public void test() {
  15. int s = 1;
  16. }
  17. public static void main(String[] args){
  18. test();
  19. }

数据类型 - 图2
而对于引用类型,则涉及堆区内存分配。其中,引用变量存储在栈区,而新建的对象则存储在堆区,当引用变量没有指向任何对象时,默认指向null
测试——演示文档

Java引用与C指针

使用上其实很类似,Java引用其底层实现也就是指针,不过Java的引用方式也更符合人的心智(至少我是这么觉得的😄。

Java, make a reference point to another reference——StackOverflow

在C中,指针自由度很高,可以得到指向指针的指针。但是在Java中,引用的处理是自动的,在作为参数去传递时,传递的是引用变量所存储的地址值。(Java强引用)