1 package javap.fload;
2
3 import static jdk.nashorn.internal.objects.Global.Infinity;
4
5 public class FloatTest {
6 public static void main(String[] args) {
7 System.out.println(+0.0F == -0.0F);
8 System.out.println(Float.intBitsToFloat(0x8000000) == -0.0F);
9
10 float res = (float) (1.2 / -0.0F);
11 System.out.println(1.2 / -0.0F); // -Infinity负无穷,任意正浮点数除以 -0.0F 得到的值
12 System.out.println(1.3 / 0.0F); // Infinity正无穷,任意正浮点数(不包括 +0.0F)除以 +0.0F 得到的值
13 System.out.println(0.0F / 0.0F); // Not-a-Number
14
15 /**
16 * 正无穷+1,还是等于正无穷
17 */
18 System.out.println("Infinity+1=" + (Infinity+1));
19
20
21 /**
22 * NaN 有一个有趣的特性:除了“!=”始终返回 true 之外,所有其他比较结果都会返回 false。
23 * 例来说,“NaN<1.0F”返回 false,而“NaN>=1.0F”同样返回 false。
24 * 对于任意浮点数 f,不管它是 0 还是 NaN,“f!=NaN”始终会返回 true,而“f==NaN”始终会返回 false。
25 */
26 // 因此,我们在程序里做浮点数比较的时候,需要考虑上述特性。在本专栏的第二部分,我会介绍这个特性给向量化比较带来什么麻烦
27 float f = 1.0F;
28 if (f != Float.NaN) { // 返回true,其余比较返回false
29 System.out.println("f != Float.NaN");
30 }
31 if (f < Float.NaN) {
32 System.out.println("f < Float.NaN");
33 }
34
35 }
36 }

结果:

true
false
-Infinity
Infinity
NaN
Infinity+1=Infinity
Infinity
f != Float.NaN

asmtools.jar的使用方法:https://wiki.openjdk.java.net/display/CodeTools/Chapter+2

OpenJDK里的AsmTools简介 http://hengyunabc.github.io/openjdk-asmtools/  (修改.class字节码的工具)

 1 MacBook-Pro-2:javap$ java -jar asmtools.jar
2 Usage:
3 to run an assembly tool:
4 $ java -jar asmtools.jar toolName [args...]
5 where toolName one of: jasm, jdis, jcoder, jdec, jcdec
6 to get the version:
7 $ java -jar asmtools.jar -version
8 to get this message
9 $ java -jar asmtools.jar -?|-h|-help
10
11 No arguments provided! See options above.

代码:(静态变量修改)

 1 package javap.fload;
2
3 public class FooBoolean {
4 static boolean boolValue;
5
6 public static void main(String[] args) {
7 boolValue = true; // 将这个true替换为2或者3,再看看打印结果
8 if (boolValue) System.out.println("Hello, Java!");
9 if (boolValue == true) System.out.println("Hello, JVM!");
10 }
11 }

javap -p -v FooBoolean.class结果:

MacBook-Pro-2:fload$ javap -p -v FooBoolean.class
Classfile /Users/wuxiong.wx/work/code/testDemo/src/main/java/javap/fload/FooBoolean.class
Last modified 2020-11-16; size 668 bytes
MD5 checksum 2693d7088f23a5890569763240da4915
Compiled from "FooBoolean.java"
public class javap.fload.FooBoolean
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #8.#25 // java/lang/Object."<init>":()V
#2 = Fieldref #7.#26 // javap/fload/FooBoolean.boolValue:Z
#3 = Fieldref #27.#28 // java/lang/System.out:Ljava/io/PrintStream;
#4 = String #29 // Hello, Java!
#5 = Methodref #30.#31 // java/io/PrintStream.println:(Ljava/lang/String;)V
#6 = String #32 // Hello, JVM!
#7 = Class #33 // javap/fload/FooBoolean
#8 = Class #34 // java/lang/Object
#9 = Utf8 boolValue
#10 = Utf8 Z
#11 = Utf8 <init>
#12 = Utf8 ()V
#13 = Utf8 Code
#14 = Utf8 LineNumberTable
#15 = Utf8 LocalVariableTable
#16 = Utf8 this
#17 = Utf8 Ljavap/fload/FooBoolean;
#18 = Utf8 main
#19 = Utf8 ([Ljava/lang/String;)V
#20 = Utf8 args
#21 = Utf8 [Ljava/lang/String;
#22 = Utf8 StackMapTable
#23 = Utf8 SourceFile
#24 = Utf8 FooBoolean.java
#25 = NameAndType #11:#12 // "<init>":()V
#26 = NameAndType #9:#10 // boolValue:Z
#27 = Class #35 // java/lang/System
#28 = NameAndType #36:#37 // out:Ljava/io/PrintStream;
#29 = Utf8 Hello, Java!
#30 = Class #38 // java/io/PrintStream
#31 = NameAndType #39:#40 // println:(Ljava/lang/String;)V
#32 = Utf8 Hello, JVM!
#33 = Utf8 javap/fload/FooBoolean
#34 = Utf8 java/lang/Object
#35 = Utf8 java/lang/System
#36 = Utf8 out
#37 = Utf8 Ljava/io/PrintStream;
#38 = Utf8 java/io/PrintStream
#39 = Utf8 println
#40 = Utf8 (Ljava/lang/String;)V
{
static boolean boolValue;
descriptor: Z
flags: ACC_STATIC public javap.fload.FooBoolean();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Ljavap/fload/FooBoolean; 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_1
1: putstatic #2 // Field boolValue:Z
4: getstatic #2 // Field boolValue:Z
7: ifeq 18
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: ldc #4 // String Hello, Java!
15: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
18: getstatic #2 // Field boolValue:Z
21: iconst_1
22: if_icmpne 33
25: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
28: ldc #6 // String Hello, JVM!
30: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
33: return
LineNumberTable:
line 7: 0
line 8: 4
line 9: 18
line 10: 33
LocalVariableTable:
Start Length Slot Name Signature
0 34 0 args [Ljava/lang/String;
StackMapTable: number_of_entries = 2
frame_type = 18 /* same */
frame_type = 14 /* same */
}
SourceFile: "FooBoolean.java"

java -jar ../asmtools.jar jdis FooBoolean.class > FooBoolean.asm.1

 1 MacBook-Pro-2:fload$ cat FooBoolean.asm.1
2 package javap/fload;
3
4 super public class FooBoolean
5 version 52:0
6 {
7
8 static Field boolValue:Z;
9
10 public Method "<init>":"()V"
11 stack 1 locals 1
12 {
13 aload_0;
14 invokespecial Method java/lang/Object."<init>":"()V";
15 return;
16
17 }
18
19 public static Method main:"([Ljava/lang/String;)V"
20 stack 2 locals 1
21 {
22 iconst_1; // 将这个替换为iconst_2或iconst_3,然后保存结果为FooBoolean.asm.2或FooBoolean.asm.3
23 putstatic Field boolValue:"Z";
24 getstatic Field boolValue:"Z";
25 ifeq L18;
26 getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
27 ldc String "Hello, Java!";
28 invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
29 L18: stack_frame_type same;
30 getstatic Field boolValue:"Z";
31 iconst_1; // 不替换,这里是true的int值
32 if_icmpne L33;
33 getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
34 ldc String "Hello, JVM!";
35 invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
36 L33: stack_frame_type same;
37 return;
38
39 }
40
41 } // end Class FooBoolean

输出结果:

$ java -jar ../asmtools.jar jasm FooBoolean.asm.1
$ java javap.fload.FooBoolean // 两行都打印输出
Hello, Java!
Hello, JVM!
$ java -jar ../asmtools.jar jasm FooBoolean.asm.2
$ java javap.fload.FooBoolean // 没有输出
$ java -jar ../asmtools.jar jasm FooBoolean.asm.3
$ java javap.fload.FooBoolean // 两行都打印输出
Hello, Java!
Hello, JVM!

解释:

  • 将局部变量区存到堆中(掩码):将boolean 保存在静态域中,指定了其类型为'Z',当修改为2时取低位最后一位为0,当修改为3时取低位最后一位为1,则说明boolean的掩码处理是取低位的最后一位
  • 将堆中的数存到局部变量区(除了long、double外都将当做int型处理): 

代码:(局部变量修改)

1 public class App{
2 public static void main(String[] args) {
3 boolean flag = true;
4 if (flag) System.out.println("Hello, Java!");
5 if (flag == true) System.out.println("Hello, JVM!");
6 }
7 }

$ java -jar asmtools.jar jdis App.class > App.asm

 1 super public class App
2 version 52:0
3 {
4
5
6 public Method "<init>":"()V"
7 stack 1 locals 1
8 {
9 aload_0;
10 invokespecial Method java/lang/Object."<init>":"()V";
11 return;
12
13 }
14
15 public static Method main:"([Ljava/lang/String;)V"
16 stack 2 locals 2
17 {
18 iconst_1; // 此处替换为2或3,相应文件为App.asm.2或App.asm.3
19 istore_1;
20 iload_1;
21 ifeq L14;
22 getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
23 ldc String "Hello, Java!";
24 invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
25 L14: stack_frame_type append;
26 locals_map int;
27 iload_1;
28 iconst_1;
29 if_icmpne L27;
30 getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
31 ldc String "Hello, JVM!";
32 invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
33 L27: stack_frame_type same;
34 return;
35
36 }
37
38 } // end Class App
 1 $ java -jar asmtools.jar jasm App.asm
2 $ java App // 输出全部
3 Hello, Java!
4 Hello, JVM!
5 $ java -jar asmtools.jar jasm App.asm.2
6 $ java App // 输出第一行
7 Hello, Java!
8 $ java -jar asmtools.jar jasm App.asm.3
9 $ java App // 输出第一行
10 Hello, Java!

参考文献:https://time.geekbang.org/column/article/11503

JVM-JAVA基本类型的更多相关文章

  1. JVM总结-java基本类型

    为什么要引进基本类型? Java 引进了八个基本类型,来支持数值计算.Java 这么做的原因主要是工程上的考虑,因为使用基本类型能够在执行效率以及内存使用两方面提升软件性能. Java 虚拟机的 bo ...

  2. Java基础类型总结

    最近一直在总结反思自己, 趁着现在请假在学校上课的空余时间,从基础开始重新温故学习下Java,充实下自己. 一.数据类型 从下图中,我们可以很清晰的看出Java中的类型,其中红色方框中的是Java的4 ...

  3. java 枚举类型分析

    最近做android开发,需要用到枚举值,这样可以连续赋值,我按之前c++那样书写,如下所示: public enum ColorSelect { RED_BAGE = 0, GREEN_BAGE, ...

  4. jvm实战-基本类型占多少内存

    jvm内存占用模型 对象的内存结构 对象头 Header 包含两部分数据Mark Word和Kclass: Mark Word:存储对象自身的运行时数据,如hashCode.GC分代年龄.锁状态标志. ...

  5. Java boolean类型

    有关java boolean类型的定义: The boolean data type has only two possible values: true and false. Use this da ...

  6. JAVA 异常类型结构分析

    JAVA 异常类型结构分析 Throwable 是所有异常类型的基类,Throwable 下一层分为两个分支,Error 和 Exception. Error 和 Exception Error Er ...

  7. Java基本类型学习

    基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型.它们是我们编程中使用最频繁的类型.java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为变量的初始化. 1. Java ...

  8. 一、JVM — Java内存区域

    Java 内存区域详解 写在前面 (常见面试题) 基本问题 拓展问题 一 概述 二 运行时数据区域 2.1 程序计数器 2.2 Java 虚拟机栈 2.3 本地方法栈 2.4 堆 2.5 方法区 2. ...

  9. JVM探秘:JVM的参数类型

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. JVM的参数类型,大致可以分为标准参数.X参数.XX参数,而XX参数又可以分为Bool ...

  10. 02 java包装类型的缓存机制

    02 java包装类型的缓存机制 Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能. Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,12 ...

随机推荐

  1. Redis解决网络抖动问题

    Redis解决网络抖动问题 所谓网络抖动问题, 简单来说就是防止用户短暂的时间内对同一个接口多次点击访问 这里利用的是redis锁的原子性和with Statement上下文管理器实现, 另外该类还支 ...

  2. KVM "shutting down, reason=crashed" 问题处理

    打开debug日志抓取信息 2022-10-12 07:42:43.698+0000: 63115: debug : processMonitorEOFEvent:4814 : Monitor con ...

  3. gulp来处理html、css、js资源啦

    gulp 一般用于处理自动化任务,默认情况无法处理模块化,也不会用于大型项目,但它可以使用各种插件来编译 html.css.js 等资源. 不清楚如何使用 gulp 开启任务的朋友可以参考 gulp使 ...

  4. 【必看!】阿里云推出QWen-7B和QWen-7b-Chat,开放免费商用!

    阿里云于8月3日宣布开源两款重要的大型模型--QWen-7B和QWen-7b-Chat.这两款模型的参数规模达到了令人瞩目的70亿,并且已经在Hugging Face和ModelScope平台上开放, ...

  5. VA01/VA02/VA03/VA05 销售订单隐藏价格

    1.业务需求 针对用户使用销售订单时,判断是否有权限,没有权限时隐藏销售订单抬头和行项目的价格相关字段 2.增强实现 2.1.隐藏抬头和行项目价格 隐藏抬头和行项目表格中的净值和净价字段 在程序MV4 ...

  6. 用了这么久SpringBoot却还不知道的一个小技巧

    前言 你可能调第三方接口喜欢启动application,修改,再启动,再修改,顺便还有个不喜欢写JUnitTest的习惯. 你可能有一天想要在SpringBoot启动后,立马想要干一些事情,现在没有可 ...

  7. msvc++中的预编译头文件pch.hpp和stdafx.h

    预编译头文件 在 Visual Studio 中创建新项目时,会在项目中添加一个名为 pch.h 的"预编译标头文件". (在 Visual Studio 2017 及更高版本中, ...

  8. 云原生 | 企业内使用 CoreDNS 构建高性能、插件化的DNS服务器

    [点击 关注「 全栈工程师修炼指南」公众号 ] 设为「️ 星标」带你从基础入门 到 全栈实践 再到 放弃学习! 涉及 网络安全运维.应用开发.物联网IOT.学习路径 .个人感悟 等知识分享. 希望各位 ...

  9. Go语句与表达式深度解析:全案例手册

    关注公众号[TechLeadCloud],分享互联网架构.云服务技术的全维度知识.作者拥有10+年互联网服务架构.AI产品研发经验.团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资 ...

  10. 「joisc 2019 - d2t2」ふたつの料理 Two Dishes

    [link.](E - ふたつの料理 (Two Dishes) (atcoder.jp) 我要放假 神仙题. 首先可以把两根轴拉成平面(which is a common trick),把决策的过程看 ...