走进 JDK 之 谈谈基本类型

简介: 除了 char 和 double,基本涵盖了 Java 的所有基本类型。今天就来总结一下基本类型的相关知识。

基本类型概述


Java 中有 8 种基本类型,如下表所示:


基本类型 大小 最大值 最小值 包装类 虚拟机中符号
boolean - - - Boolean Z
char 16 bits 65536 0 Character C
byte 8 bits 127 -128 Byte B
short 16 bits 215-1 - 215 Short S
int 32 bits 231-1 231 Integer I
long 64 bits 263-1 -263 Long J
float 32 bits 3.4028235e+38f -3.4028235e+38f Float F
double 64 bits 1.7976931348623157e+308 -1.7976931348623157e+308 Double D


每种基本类型所占的存储空间大小不会随着机器硬件架构的变化而变化,具有良好的可移植性。


数值类型有 byteshortintlongfloatdouble。其中 byteshortintlong 是整数类型。floatdouble 是浮点数类型,分别表示单精度和双精度,遵循 IEEE 754 浮点数标准。Java 中所有数值类型都是有符号数,最高位表示符号位。


boolean 是布尔类型,只有两个值 TRUEFALSE,在 JVM 中当做 int 处理,两个值分别为 10


char 是字符类型,为 Unicode 编码。在某些应用场景下,可以把 char 当作无符号数来处理。


对于上面表格中的内容,还有几点需要说明一下:

溢出问题

整数类型都有自己的取值范围,如果强行超出它的范围会怎么样呢?如下面代码:

public void test() {
    byte max = Byte.MAX_VALUE;
    byte over = (byte) (max + 1);
    System.out.println(over);
}
复制代码


打印结果是 -128,即 Byte.MIN_VALUE。你可以把值域范围想象成时钟的刻度,最大值是 12 ,最小值是 0 ,已经到了最大值 12 ,你还要再加 1 ,就发生了溢出,又回到了最小值 0 。

栈上大小


在栈上,byteshortbooleanchar 占用的空间和 int 是一致的,都是占一个 slotlongdouble 是占用两个 slot。具体原因在之前的文章中具体分析过,这里再总结一下:

  • 局部变量表可以看成一个 slot 数组,这样设计方便使用索引来获取数据
  • 操作码是单字节的,最多只有 256 个字节码指令,不可能为每一个基本数据类型提供完整的指令支持。

当然,这仅仅只是针对栈上,对于堆上和数组中分配的基本类型,其大小还是和表中匹配的。

  • 不同类型的字节码指令处理


这块内容在 走进 JDK 之 Boolean 中详细介绍过。操作码是单字节的,最多只有 256 个字节码指令,不可能为每一个基本数据类型提供完整的指令支持。大部分的指令都没有支持 bytecharshortboolean 则更惨,没有任何指令支持 boolean 类型。对于这些不支持的指令类型,一律使用 int 的相关指令代替。


对于不确定的情况,你可以看一下 class 文件中的字节码:

javac Test.java
javap -v Test.class
复制代码


为什么需要基本类型 ?


基本所有语言都有基本数据类型,Java 当然也是如此。标榜 万物皆对象 的 Java 为什么需要基本数据类型的存在呢?回顾一下你的职业生涯中写过的代码,基本数据类型出现的概率可以说相当之高,基本数据类型是直接存储在栈内存的,而 new 出来的对象是存储在堆内存中的。显然对象占用的内存是高于基本数据类型的。对象在内存中存储的布局可以分为 3 块区域:对象头实例数据对齐填充。如果把你的代码中所有基本类型全部替换为其包装类,无疑会占用更多的内存,也降低了运行效率。


为什么需要包装类 ?


就冲那句 万物皆对象 ,当然也得有包装类了!开个玩笑而已 ... 基本数据类型占用内存更少,运行速度更快,但它也有办不到的事情,比如我要构造一个包含 intList 集合:

List list = new ArrayList<int>();
复制代码


显然这是没法通过编译的。这里我们传进去的必须是一个对象,所以基本数据类型还必须得有一个包装类。包装类中包装了基本类型的数值,并且提供了一系列处理数值的方法,就像前面分析的过得源码中各种方法,丰富了基本数据类型的功能。


自动拆箱与自动装箱


把基本数据类型转换成包装类的过程叫做装箱。

把包装类转换成基本数据类型的过程叫做拆箱。

在Java SE 5.0 之前,装箱和拆箱需要手动进行。可能 Java 开发者们觉得这样实在太不人性化了,一切应该以提高生产力为主,在 Java SE 5.0 中就推出了自动装箱和拆箱。以 Integer 为例:

Integer i = 10;  //自动装箱
int b = i;     //自动拆箱
复制代码


我们已经解析过 Integer 的源码,不难想象,自动装箱和拆箱必然是调用了包装类的某些方法,javap 看一下字节码:

2: invokestatic  #2         // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: aload_1
7: invokevirtual #3         // Method java/lang/Integer.intValue:()I
复制代码


很明了,之前的代码经过编译器编译,已经改变了模样:

Integer i = Integer.valueOf(10);  //装箱
int b = i.intValue();     //拆箱
复制代码


还记得 valueOf() 方法吗?

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
复制代码


通过 IntegerCache 缓存了 -128127。在此范围内直接返回缓存的实例,否则创建新对象。

不仅仅是 Integer,其他基本数据类型也都是使用类似 valueOf()xxxValue() 方法来进行自动装箱和拆箱的。


现在你应该知道了自动装箱和自动拆箱实际上是编译器在里面做了手脚,和 Java 虚拟机并没有什么关系。编译器在生成类的字节码时,插入必要的方法调用。虚拟机只是执行这些字节码。


最后


走进 JDK 系列的基本数据类型部分就说到这里了

下一篇是 走进 JDK 之 String,不出意外的话应该要过几天,String 的内容还是比较多的,可以先阅读阅读我之前的一篇文章 String 为什么不可变?



相关文章
|
3月前
|
Java
安装JDK18没有JRE环境的解决办法
安装JDK18没有JRE环境的解决办法
381 3
|
5月前
|
Oracle Java 关系型数据库
入职必会-开发环境搭建41-Linux软件安装-安装JDK
本文介绍了在Linux系统中下载和安装JDK
189 3
入职必会-开发环境搭建41-Linux软件安装-安装JDK
|
4月前
|
Oracle Java 关系型数据库
Mac安装JDK1.8
Mac安装JDK1.8
774 4
|
4月前
|
Java 关系型数据库 MySQL
"解锁Java Web传奇之旅:从JDK1.8到Tomcat,再到MariaDB,一场跨越数据库的冒险安装盛宴,挑战你的技术极限!"
【8月更文挑战第19天】在Linux上搭建Java Web应用环境,需安装JDK 1.8、Tomcat及MariaDB。本指南详述了使用apt-get安装OpenJDK 1.8的方法,并验证其版本。接着下载与解压Tomcat至`/usr/local/`目录,并启动服务。最后,通过apt-get安装MariaDB,设置基本安全配置。完成这些步骤后,即可验证各组件的状态,为部署Java Web应用打下基础。
65 1
|
5月前
|
Java Linux
Linux复制安装 jdk 环境
Linux复制安装 jdk 环境
115 3
|
1月前
|
Oracle Java 关系型数据库
安装 JDK 时应该注意哪些问题
选择合适的JDK版本需考虑项目需求与兼容性,推荐使用LTS版本如JDK 17或21。安装时注意操作系统适配,配置环境变量PATH和JAVA_HOME,确保合法使用许可证,并进行安装后测试以验证JDK功能正常。
53 1
|
1月前
|
IDE Java 编译器
开发 Java 程序一定要安装 JDK 吗
开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
70 1
|
4月前
|
Java 开发工具
开发工具系列 之 同一个电脑上安装多个版本的JDK
这篇文章介绍了如何在一台电脑上安装和配置多个版本的JDK,包括从官网下载所需JDK、安装过程、配置环境变量以及如何查看和切换当前使用的JDK版本,并提到了如果IDEA和JDK版本不兼容时的解决方法。
开发工具系列 之 同一个电脑上安装多个版本的JDK
|
2月前
|
Oracle Java 关系型数据库
jdk17安装全方位手把手安装教程 / 已有jdk8了,安装JDK17后如何配置环境变量 / 多个不同版本的JDK,如何配置环境变量?
本文提供了详细的JDK 17安装教程,包括下载、安装、配置环境变量的步骤,并解释了在已有其他版本JDK的情况下如何管理多个JDK环境。
1435 0
|
3月前
|
Oracle Java iOS开发
JDK的选型、安装与配置
JDK的选型、安装与配置
133 1