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

极客时间深入理解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. Netty源码分析第5章(ByteBuf)---->第6节: 命中缓存的分配

    Netty源码分析第6章: ByteBuf 第六节: 命中缓存的分配 上一小节简单分析了directArena内存分配大概流程, 知道其先命中缓存, 如果命中不到, 则区分配一款连续内存, 这一小节带 ...

  2. php从入门到放弃系列-03.php函数和面向对象

    php从入门到放弃系列-03.php函数和面向对象 一.函数 php真正的威力源自它的函数,内置了1000个函数,可以参考PHP 参考手册. 自定义函数: function functionName( ...

  3. MCS锁——可伸缩的自旋锁

    在编写并发同步程序的时候,如果临界区非常小,比如说只有几条或几十条指令,那么我们可以选择自旋锁(spinlock).使用普通的互斥锁会涉及到操作系统的调度,因此小临界区一般首选自旋锁.自旋锁的工作方式 ...

  4. 浏览器差异bug汇总(js篇)

    获取滚动条高度 var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; safari浏览器时间函数 ...

  5. LeetCode 174. Dungeon Game (C++)

    题目: The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dung ...

  6. final发布视频展示博客

    Part One [探路者]选题展示视频链接: http://v.youku.com/v_show/id_XMzIxMDM2MTQ1Ng==.html?spm=a2h3j.8428770.341605 ...

  7. Linux基础入门--01~03

  8. 第四节 Linux目录文件及文件基本操作

    一.Linux目录结构 Linux 的目录与 Windows 的目录的区别: 一种不同是体现在目录与存储介质(磁盘,内存,DVD 等)的关系上,以往的 Windows 一直是以存储介质为主的,主要以盘 ...

  9. 每日scrum(1)

    今天又正式开始了第二个冲刺周期,计划十天,主要需要改进的地方包括UI界面,还有一些细节的把握. 今天出现的主要问题有:在讨论UI界面风格的时候,小组内部意见不统一,对UI界面的创作流程不熟悉,以及难度 ...

  10. 【TCP/IP详解 卷一:协议】第六章:DHCP 和自动配置

    简介 为了使用 TCP/IP 协议族,每台主机or路由器都需要一定的配置信息: IP地址 子网掩码 广播地址 路由或转发表 DNS 协议配置方法: 手动 通过使用网络服务来获得 使用一些算法来自动确定 ...