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. MAUI Blazor项目中如何添加一个返回服务,并支持安卓返回键

    前言 MAUI Blazor中,安卓项目的返回键体验很不好,只能如同浏览器一样返回上一页.但很多时候,我们想让他返回的上一页,不一定就是实际上的上一页.而且也想让返回键去支持一些事件,按下返回键触发, ...

  2. Python中的弱引用与基础类型支持情况探究

    背景 最近有一个业务场景需要用Python自行实现一个简单的LRU cache,不可避免的接触到了弱引用这一概念,这里记录一下. 强引用 Python内存回收由垃圾回收器自动管理,当一个对象的引用计数 ...

  3. linux 字符集与编码格式相关

    字符集:​多个字符的集合. # 书写系统字母与符号的集合. 字符编码:​把 字符集 中的字符 编码为(映射)指定集合中的某一对象. # 以便文本在计算机中存储和通过通信网络的传递 查看文件的的编码格式 ...

  4. Linux基础—vmvare安装及centos7安装

    Linux基础 # https://zhuanlan.zhihu.com/p/429509333 # 一 什么是操作系统 Operating System(操作系统) 简称OS Windows,Mac ...

  5. openpyxl 设置某列单元格样式

    1 # 边框线 2 border_set = Border(left=Side(border_style='thin', color='000000'), 3 right=Side(border_st ...

  6. [PWN之路]堆攻击那些事儿

    原文:https://www.freebuf.com/articles/endpoint/371095.html 0x00 前言 根据某大佬所说,pwn之路分为栈,堆,和内核.当前,如果你看到这个文章 ...

  7. 集训后的一些wp

    新生赛后 0x01 2048(jk出发) 修改跳转条件为nop,随便动一下直接打印flag.这个场景我幻想过很久了,一直没做到,这次参考wp做出来了知道怎么做了.学到! 0x02 four(dsact ...

  8. SpringBoot 测试实践 - 2:单元测试与集成测试

    单元测试 vs. 集成测试 只编写单测,无法测试方法之间的集成情况,而且某些需求可能会修改多个方法,这可能会影响方法对应的单测,涉及到大量的相关单测的修改,这样的维护成本很高 可以把重心放在完善集成测 ...

  9. ChatGPT应用篇:如何快速生成精美PPT提高工作效率-附资料下载

    一.ChatGPT生成markdown源代码 问: 我想做一份ChatGPT变现方法的PPT,请生成丰富的教学展示内容,因为生成PPT是需要MarkDown格式的,请您输出Markdown格式的内容 ...

  10. 通过AOP拦截Spring Boot日志并将其存入数据库

    本文分享自华为云社区<Spring Boot入门(23):[实战]通过AOP拦截Spring Boot日志并将其存入数据库>,作者:bug菌. 前言 在软件开发中,常常需要记录系统运行时的 ...