《深入理解Java虚拟机》-(实战)boolean类型在虚拟机中是如何处理的
这里先引出Java的8大基本类型。直接上图吧。

可以看到,除了boolean和char类型之外,越往下的类型的值域是包含以上的值域的。因此,从上面的基本类型转换成下面的基本类型,无需强制转换。关于它们的默认值,在内存中保存的都是0。
对于char类型,菜鸟喜鹊有些感悟,就是char类型转成int类型的例子很多。
今天上班忙里抽闲学习了一下"AC自动机"的实现,其中就是模式串构建tired树的时候的char类型处理的时候,直接使用它与'a'相减,得到数组下标的。这里也算是用了一个转换吧。还有String类里的indexOf(int n)也是。
读者有空可以去看看。
对于boolean类型,上图的表格里是true和false的值。可是,从jvm角度来看,可不一样。在这里,你可以参照我上一篇文章写的字节码文章改一下。将值iconst_1改成iconst_3,iconst_4,iconst_5看看有什么结果。再看看我这里的结论。
ok! talk is cheap,show you my code!
(以下操作在linux进行)
1.编写Foo.java
public class Foo {
static boolean boolValue;
public static void main(String[] args) {
boolValue = true; // 将这个 true 替换为 2 或者 3,再看看打印结果
if (boolValue) System.out.println("Hello, Java!");
if (boolValue == true) System.out.println("Hello, JVM!");
}
}
2.编译运行
[root@localhost tmp2]# javac Foo.java
[root@localhost tmp2]# java Foo
Hello, Java!
Hello, JVM!
3.查看class字节码(这里就不看了,就看boolValue的值就好了。上一篇文章中有演示过(https://www.cnblogs.com/chenscript/p/11343270.html))
4.修改常量值分别为4和5,编译并输出结果:
[root@localhost tmp2]# awk 'NR==1,/iconst_1/{sub(/iconst_1/,"iconst_4")} 1' Foo.jasm.1>Foo.jasm
[root@localhost tmp2]# java -jar ../asmtools.jar jasm Foo.jasm
[root@localhost tmp2]# java Foo
(改成4的时候,没有输出!)
[root@localhost tmp2]# awk 'NR==1,/iconst_1/{sub(/iconst_1/,"iconst_5")} 1' Foo.jasm.1>Foo.jasm
[root@localhost tmp2]# java -jar ../asmtools.jar jasm Foo.jasm
[root@localhost tmp2]# java Foo
Hello, Java!
Hello, JVM!
这里,我们就该查看一下字节码:
5.这里就贴关键部分的字节码吧。
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iconst_4 //
1: putstatic #5 // Field boolValue:Z
4: getstatic #5 // Field boolValue:Z
7: ifeq 18
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: ldc #2 // String Hello, Java!
15: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
18: getstatic #5 // Field boolValue:Z
21: iconst_1 //
22: if_icmpne 33
25: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
28: ldc #1 // String Hello, JVM!
30: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
33: return
StackMapTable: number_of_entries = 2
frame_type = 18 /* same */
frame_type = 14 /* same */
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: iconst_5 //
1: putstatic #5 // Field boolValue:Z
4: getstatic #5 // Field boolValue:Z
7: ifeq 18
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: ldc #2 // String Hello, Java!
15: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
18: getstatic #5 // Field boolValue:Z
21: iconst_1 //
22: if_icmpne 33
25: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
28: ldc #1 // String Hello, JVM!
30: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
33: return
StackMapTable: number_of_entries = 2
frame_type = 18 /* same */
frame_type = 14 /* same */
总结上面的输出:
如果单从肉眼看,按照上一篇的学习,改写成4和5的时候,ifeq比较的值是0,0与4、5怎么可能匹配得上?但是在改成iconst_5的时候,虚拟机就判断是不相等,然后输出“Hello,Java”,改成4的时候,就相等,直接跳转。
为什么呢?
这里面是有点玄机。
根据http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html官方文档的描述:
boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined.
官方说:
布尔类型:布尔数据类型只有两个可能的值:真和假。使用此数据类型为跟踪真/假条件的简单标记。这种数据类型就表示这一点信息,但是它的“大小”并不是精确定义的。
由于笔者实力有限,也只能到这一步了。但根据实际操作看推测的话,这个二进制有关,也就是比较的值都是使用二进制的最低位进行比较的。也就是,4的二进制100,5 的二进制是101,取最低位,就是0和1了。这里机器码中的0是false,1是true~就这样吧~
Java基本类型在局部变量区(属于Java方法栈)和堆中的存储大小是有区别的:
主要表现于:boolean、byte、char、short 这几个的存储大小根据环境不同而不同
局部变量区:在32位的hotspot中都是占用4个字节,而在64位的hotspot中占用8个字节。
堆:byte、char、short分别占一字节、两字节、两字节。(也就是跟这些的值域相吻合的~~)
以上~
《深入理解Java虚拟机》-(实战)boolean类型在虚拟机中是如何处理的的更多相关文章
- 深入理解JAVA I/O系列六:Linux中的IO模型
IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器, ...
- 深入理解JAVA I/O系列六:Linux中的IO模型(转载的文章非常值得学习)
From:http://www.cnblogs.com/dongguacai/p/5770287.html IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大 ...
- 深入理解Java的整型类型:如何实现2+2=5?
先看下这段神奇的Java代码: public static void main(String[] args) throws Exception { doSomethingMagic(); System ...
- 在MySql中如何定义像Java中类型的Boolean类型
在MySql中如何定义像Java中类型的Boolean类型数据..其实,mysql中 是没有直接定义成Boolean这种数据类型.它只能定义成 tinyint(1) ;如果长度是1,tinyint(1 ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- 从零开始理解JAVA事件处理机制(3)
我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...
- java为什么要用类型擦除实现泛型?--c++,java,c# 的泛型是如何实现的
所以总结一下c++,java,c#的泛型.c++的泛型在编译时完全展开,类型精度高,共享代码差.java的泛型使用类型擦出,仅在编译时做类型检查,在运行时擦出,共享代码好,但是类型精度不行.c#的泛型 ...
- OpenStack 虚拟机的磁盘文件类型与存储方式
目录 文章目录 目录 虚拟机的磁盘文件类型 虚拟机磁盘文件的存放方式 QCOW2 镜像格式与 qemu-img 指令 参考文章 虚拟机的磁盘文件类型 Nova 虚拟机的虚拟磁盘主要包含有 Root D ...
- 第一百零七篇:基本数据类型(undefined,null,boolean类型)
好家伙, 本篇内容为<JS高级程序设计>第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Numb ...
随机推荐
- java 多级图的最短路径
求最短路径众所周知有Dijistra算法.Bellman-ford等,除了这些算法,用动态规划也可以求出最短路径,时间复杂度为O(n^2), 跟没有优化的Dijistra算法一样(优化后的Dijist ...
- 【C++第一个Demo】---控制台RPG游戏3【登陆菜单树】
[登陆系统--树结构] 1 首先我这里设计,由一个基类MainMenu构建树结构,并实现控制台上菜单之间的切换和返回操作 #ifndef _UI_BASE_H_ #define _UI_BASE_H_ ...
- Rust <4>:所有权、借用、切片
tips:栈内存分配大小固定,访问时不需要额外的寻址动作,故其速度快于堆内存分配与访问. rust 所有权规则: 每一个值在任意时刻都有且只有唯一一个所有者 当所有者离开作用域时,这个值将被丢弃 所有 ...
- Java异常处理教程
异常是在没有定义正常执行路径时在Java程序的执行期间可能出现的条件.Java通过将执行操作的代码与处理错误的代码分离来处理错误. 当发生异常时,Java会创建一个包含有关异常的所有信息的对象,并将其 ...
- lambda(),map(),filter()
Lambda 函数 Lambda 函数是一种比较小的匿名函数.Python 函数通常使用 def a_function_name() 样式来定义,但对于 lambda 函数,我们根本没为它命名.这是因 ...
- php中mkdir()函数的权限问题(转)
问题描述: 使用以下php代码创建了一个目录,期望目录的权限是0777,实际结果是0755 mkdir('./aa/',0777); 分析与测试结果: 1.mkdir()函数指定的目录权限只能小于等于 ...
- 算法竞赛模板 KMP
KMP算法图解: ① 首先,字符串“BBC ABCDAB ABCDABCDABDE”的第一个字符与搜索词“ABCDABD”的第一个字符,进行比较.因为B与A不匹配,所以搜索词后移一位. ② 因为B与A ...
- UICollectionView中的cell包含UIScrollview
需求:在scrollview的子View不为0,当scrollview的展示的index不为0且向右滑动CollectionView.CollectionView不滑动Cell,而是让scrollvi ...
- linux学习总结--linux100day(day1)
写在前面:我是一名在学习linux的小学生,最近在学习python时,我的老师推荐了github上的一本教材“python100day”,100day里面的内容由浅入深,且都具备详细的例子,对于我这个 ...
- linux系统物理cpu信息查询
1.查看CPU型号 cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 2.查看物理CPU的个数 ca ...