基本数据类型的加载和存储

极客时间深入理解Java虚拟机读后感,有错误还请指正

虚拟机中的Boolean类型

在Java语言规范中,boolean类型的值只有两种可能,那就是"true"和"false". 但是这两个符号是不能被Java虚拟机直接使用的.

在Java虚拟机规范中,boolean类型则被映射成int类型. 也就是说,"true"被映射为整数1,"false"被映射为整数0.这个编码规则约束了Java字节码的具体实现.

Java中的基本类型

Java中的基本类型有8个,上面的boolean类型, 整数类型的byte、short、char、int和 long,以及浮点类型 float 和 double.

java的基本类型都有对应的值域和默认值,如图,从上到下的值域一次增大,后面的值域包含前面的值域,意味着上面的数据类型转换为下面的数据类型不需要进行强制转换。还有注意默认值看起来不一样,实际在内存中都是0。

8个基本数据类型中,只有char和boolean是无符号数。并且boolean类型的取值范围为0或者1,char类型的取值范围为[0,65535]。通常我们认为char类型的值为非负数。

Java 的浮点类型采用 IEEE 754 浮点数格式。以 float 为例,浮点类型通常有两个 0,+0.0F 以及 -0.0F。前者在 Java 里是 0,后者是符号位为 1、其他位均为 0 的浮点数,在内存中等同于十六进制整数 0x8000000(即 -0.0F 可通过Float.intBitsToFloat(0x8000000) 求得)。尽管它们的内存

数值不同,但是在 Java 中 +0.0F == -0.0F 会返回真。

有了+0.0F和-0.0F后,那么浮点数中的正无穷和负无穷就可以定义了。正无穷就是任意正浮点数(不包括 +0.0F)除以 +0.0F 得到的值,而负无穷是任意正浮点数除以 -0.0F得到的值。在 Java 中,正无穷和负无穷是有确切的值,在内存中分别等同于十六进制整数0x7F800000 和 0xFF800000。

那超出范围的数字呢? 对应的是NaN(Not-a-Number),0x7FC00000为标准的NaN,其他的称之为不标准的NaN。并且NaN有一个特性,任何数 != NaN 永远返回true。

Java基本类型的大小

存储时的大小

Java 虚拟机每调用一个 Java 方法,便会创建一个栈帧。暂时理解为解释器使用的解释栈帧。包括两个组成部分,局部变量区和字节码操作数栈。

在Java虚拟机规范中,局部变量区等价于一个数组,并且可以用正整数索引。除了long、double值需要用两个数组单元来存储之外,其他的基本类型以及引用类型的值均占用一个数组单元。

也就是说,boolean、byte、char、short这四种类型,在栈上占用的空间和int是一样的,和引用类型也是一样的。也就是32位的HotSpot上,栈上占用4个字节;64位的HotSpot上,占用8个字节。

当然,这种情况仅存在于局部变量,而并不会出现在存储于堆上的字段和数组元素上。对于byte、char以及short这三种类型的字段或者数组单元,他们在堆上占用的空间分别为一字节、两字节以及两字节,与值域是相吻合的。

因此,当我们将一个 int 类型的值,存储到这些类型的字段或数组时,相当于做了一次隐式的掩码操作。举例来说,当我们把0xFFFFFFFF(-1)存储到一个声明为 char 类型的字段里时,由

于该字段仅占两字节,所以高两位的字节便会被截取掉,最终存入“\uFFFF”。

boolean 字段和 boolean 数组则比较特殊。在 HotSpot 中,boolean 字段占用一字节,而boolean 数组则直接用 byte 数组来实现。为了保证堆中的 boolean 值是合法的,HotSpot 在存储时显式地进行掩码操作,也就是说,只取最后一位的值存入boolean 字段或数组中。

加载时的大小

Java 虚拟机的算数运算几乎全部依赖于操作数栈。也就是说,我们需要将堆中的 boolean、byte、char 以及 short 加载到操作数栈上,而后将栈上的值当成 int 类型来运算。

对于 boolean、char 这两个无符号类型来说,加载伴随着零扩展。举个例子,char 的大小为两个字节。在加载时 char 的值会被复制到 int 类型的低二字节,而高二字节则会用 0 来填充。

对于 byte、short 这两个类型来说,加载伴随着符号扩展。举个例子,short 的大小为两个字节。在加载时 short 的值同样会被复制到 int 类型的低二字节。如果该 short 值为非负数,即最

高位为 0,那么该 int 类型的值的高二字节会用 0 来填充,否则用 1 来填充。

总结

其中,boolean 类型在 Java 虚拟机中被映射为整数类型:“true”被映射为 1,而“false”被映射为 0。Java 代码中的逻辑运算以及条件跳转,都是用整数相关的字节码来实现的。

除 boolean 类型之外,Java 还有另外 7 个基本类型。它们拥有不同的值域,但默认值在内存中均为 0。这些基本类型之中,浮点类型比较特殊。基于它的运算或比较,需要考虑+0.0F、-0.0F 以及 NaN 的情况。

除 long 和 double 外,其他基本类型与引用类型在解释执行的方法栈帧中占用的大小是一致的,但它们在堆中占用的大小确不同。在将 boolean、byte、char 以及 short 的值存入字段或

者数组单元时,Java 虚拟机会进行掩码操作。在读取时,Java 虚拟机则会将其扩展为 int 类型。

我的理解

从这个中,可以学到,8种基本数据的大小,还有虚拟机对于基本数据类型的规范是什么,堆上和解释执行的方法栈帧上的byte、short、char、boolean类型的存储的大小是不一样的,加载(读取)的时候,会进行掩码的操作。

Java的基本类型的更多相关文章

  1. java基础--java.util.Date类型小结

    首先先来了解一下Date数据类型: . Date类型通常要和另一个 java.text.SimpleDateFormat类联合使用. 把long-->Date: public Date(long ...

  2. java mysql 日期类型

    mysql(版本:5.1.50)的时间日期类型如下: datetime 8bytes xxxx-xx-xx xx:xx:xx 1000-01-01 00:00:00到9999-12-31 23:59: ...

  3. 关于Java的基本类型

    Java的基本类型分为整数型,浮点型,字符型,布尔型.顾名思义整数型用来表示整数,浮点型用来表示带小数的数,字符型用来表示字符.特殊的是布尔型用来表示逻辑上的true(真)和false(假),一般与分 ...

  4. Android java传递int类型数组给C

    接着前面的文章<Android java传递int类型数据给C><Android java传递string类型数据给C>,继续实践 实现public native int[] ...

  5. Android java传递string类型数据给C

    本文接着实现<Android java传递int类型数据给C>的还未实现的方法: public native String sayHelloInC(String s); 先贴一个工具方法, ...

  6. Android java传递int类型数据给C

    本文根据<Android jni简便开发流程>中的开发流程来实现一个java传递int类型数据给C 新建项目,进行简单的布局 <LinearLayout xmlns:android= ...

  7. Java中静态类型检查是如何进行的

    以下内容来自维基百科,关于静态类型检查和动态类型检查的解释: 静态类型检查:基于程序的源代码来验证类型安全的过程: 动态类型检查:在程序运行期间验证类型安全的过程: Java使用静态类型检查在编译期间 ...

  8. 关于java中Double类型的运算精度问题

    标题     在Java中实现浮点数的精确计算    AYellow(原作) 修改    关键字     Java 浮点数 精确计算   问题的提出:如果我们编译运行下面这个程序会看到什么?publi ...

  9. JAVA修饰符类型(public,protected,private,friendly)

    转自:http://www.cnblogs.com/webapplee/p/3771708.html JAVA修饰符类型(public,protected,private,friendly) publ ...

  10. Java web项目引用java项目,类型找不到

    Java web项目引用java项目,类型找不到 错误信息: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapp ...

随机推荐

  1. Log4j简单配置解析

    log4j.rootLogger=ERROR, stdoutlog4j.logger.tk.mybatis.simple.mapper=TRACElog4j.appender.stdout=org.a ...

  2. 配置Tomcat使用HTTP/2

    转自: https://zhuanlan.zhihu.com/p/21349186 前情提要: Tomcat高效响应的秘密(一) Sendfile与Gzip Tomcat高效响应的秘密(二) keep ...

  3. 硬件设计原理图Checklist 参考案例二 【转载】

    类别 描述 检视规则 原理图需要进行检视,提交集体检视是需要完成自检,确保没有低级问题. 检视规则 原理图要和公司团队和可以邀请的专家一起进行检视. 检视规则 第一次原理图发出进行集体检视后所有的修改 ...

  4. Linux第一二章笔记

    第一章 Linux内核简介 1. Unix内核的特点 简洁:仅提供系统调用并有一个非常明确的设计目的 抽象:几乎所有东西都被当做文件 可移植性:使用C语言编写,使得其在各种硬件体系架构面前都具备令人惊 ...

  5. 仿ArrayList功能的bag类

    仿ArrayList功能的bag类 要想做到能够实现ArrayList功能,首先要有一个能往里填任何类型元素的的空间,但是不能用ArrayList来创建空间,这样这个项目就没有意义,因此,我创建了一个 ...

  6. 20162327WJH第二次实验——树

    20162327WJH第一次实验--线性结构 实 验 报 告 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验 ...

  7. Java每日学习笔记1

    单选按钮 JRadioButton radioButton1 = new JRadioButton("Java");// 创建单选按钮 contentPane.add(radioB ...

  8. 【CSAPP笔记】8. 汇编语言——数据存储

    下面介绍一些C语言中常见的特殊的数据存储方式,以及它们在汇编语言中是如何表示的. 数组 数组是一种将标量数据聚集成更大数据类型的方式.实现数组的方式其实十分简单,也非常容易翻译成机器代码.C语言的一个 ...

  9. 详解Android微信登录与分享

    Android 使用微信登录.分享功能 具体的文档详情微信官网上介绍(微信官网文档),本人直接按照项目部署步骤进行讲解: 第一步:申请你的AppID: 第二步:依赖 dependencies { co ...

  10. 获取SQL Server中连接的客户端IP地址[转]

    有时候需要获取连接到SQL Server服务器上的客户端IP地址,用什么办法呢? SELECT *FROM sys.dm_exec_connections WHERE session_id = @@S ...