这里先引出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类型在虚拟机中是如何处理的的更多相关文章

  1. 深入理解JAVA I/O系列六:Linux中的IO模型

    IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器, ...

  2. 深入理解JAVA I/O系列六:Linux中的IO模型(转载的文章非常值得学习)

    From:http://www.cnblogs.com/dongguacai/p/5770287.html IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大 ...

  3. 深入理解Java的整型类型:如何实现2+2=5?

    先看下这段神奇的Java代码: public static void main(String[] args) throws Exception { doSomethingMagic(); System ...

  4. 在MySql中如何定义像Java中类型的Boolean类型

    在MySql中如何定义像Java中类型的Boolean类型数据..其实,mysql中 是没有直接定义成Boolean这种数据类型.它只能定义成 tinyint(1) ;如果长度是1,tinyint(1 ...

  5. 深入理解Java并发之synchronized实现原理

    深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...

  6. 从零开始理解JAVA事件处理机制(3)

    我们连续写了两小节的教师-学生的例子,必然觉得无聊死了,这样的例子我们就是玩上100遍,还是不知道该怎么写真实的代码.那从本节开始,我们开始往真实代码上面去靠拢. 事件最容易理解的例子是鼠标事件:我们 ...

  7. java为什么要用类型擦除实现泛型?--c++,java,c# 的泛型是如何实现的

    所以总结一下c++,java,c#的泛型.c++的泛型在编译时完全展开,类型精度高,共享代码差.java的泛型使用类型擦出,仅在编译时做类型检查,在运行时擦出,共享代码好,但是类型精度不行.c#的泛型 ...

  8. OpenStack 虚拟机的磁盘文件类型与存储方式

    目录 文章目录 目录 虚拟机的磁盘文件类型 虚拟机磁盘文件的存放方式 QCOW2 镜像格式与 qemu-img 指令 参考文章 虚拟机的磁盘文件类型 Nova 虚拟机的虚拟磁盘主要包含有 Root D ...

  9. 第一百零七篇:基本数据类型(undefined,null,boolean类型)

    好家伙, 本篇内容为<JS高级程序设计>第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Numb ...

随机推荐

  1. 使用apache搭建tomcat集群

    1.安装apache 1.1 下载ApacheX64.rar,并解压 1.2 修改Apache24\conf\httpd.conf文件 配置根目录: 配置ip和端口 1.2 安装apache服务器 以 ...

  2. bootstrap学习(五)代码

    内联代码: <code>public static</code>void main 用户输入: to edit setting,press <kbd><kbd ...

  3. sleep()方法和wait()方法的区别? sleep()方法和yield()方法的区别?

    sleep()方法和wait()方法的区别? sleep方法是Thread的静态方法,wait方法是Object类的普通方法 sleep方法不释放同步锁,wait方法释放同步锁(执行notify方法唤 ...

  4. Spark使用Java读取mysql数据和保存数据到mysql

    原文引自:http://blog.csdn.net/fengzhimohan/article/details/78471952 项目应用需要利用Spark读取mysql数据进行数据分析,然后将分析结果 ...

  5. Android Service完全解析(上)

    转载:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Androi ...

  6. Codeforces 346D Robot Control DP spfa 01BFS

    题意及思路:https://www.cnblogs.com/zjp-shadow/p/9562888.html 这题由于性质特殊,可以用01BFS来进行DP的转移. 代码: #include < ...

  7. 如何将项目中的package.json文件中的模块更新到最新版本

    有时候自己之前开发的项目回头运行的时候发行好多模块的版本不是最新的,此时想更为为最新版本,使用如下命令即可: npm i -g npm-check-updates ncu -u npm install

  8. 思维——cf1238C

    听思维的一道题,网上大多直接模拟,感觉有点麻烦,其实只要把连续段求出来,然后处理一下统计答案就行 两个注意点:1.除了第一个连续段,其余段长度都要+1 2.因为目的地是0,所以最后一段要特判一下 #i ...

  9. CF 1082E Increasing Frequency(贪心)

    传送门 解题思路 贪心.对于一段区间中,可以将这段区间中相同的元素同时变成\(c\),但要付出的代价是区间中等于\(c\)的数的个数,设\(sum[i]\)表示等于\(c\)数字的前缀和,Max[i] ...

  10. websocke和http的区别

    同:建立在TCP之上,同http一样通过TCP来传输数据 不同: HTTP协议为单向协议,即浏览器只能向服务器请求资源,服务器才能将数据传送给浏览器,而服务器不能主动向浏览器传递数据.分为长连接和短连 ...