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. 【技术积累】Java中的常用类【一】

    Math类 Math类是Java中的一个数学工具类,提供了一系列常用的数学方法.下面是Math类的常用方法及其案例: abs() 返回一个数的绝对值. int num = -10; int absNu ...

  2. c# 文件在线预览功能

    using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using DocumentF ...

  3. Java面试题全集(二)

    1. ⾸先CopyOnWriteArrayList内部也是⽤过数组来实现的,在向CopyOnWriteArrayList添加元素时,会复制⼀个新的数组,写操作在新数组上进⾏,读操作在原数组上进⾏ 2. ...

  4. js中调用函数中的变量

    (function f1() { var num = 10; window.num = num;})(); console.log(num);

  5. python爬虫抓取图片

    一.什么是爬虫 什么是爬虫?爬虫是蜘蛛么?是八爪鱼么?nonono. 爬虫是指请求网站并获取数据的自动化程序,又称网页蜘蛛或网络机器,最常用领域是搜索引擎,最常用的工具是八爪鱼. 它的基本流程分为以下 ...

  6. Linux 身份验证被拒绝,登录失败解决

    解决方案: vim /etc/ssh/sshd_config 修改参数 基本参数: PermitRootLogin yes #允许root认证登录 PasswordAuthentication yes ...

  7. 你能看到这个汉字么“  ” ?关于Unicode的私人使用区(PUA) 和浏览器端显示处理

    如果你现在使用的是chrome查看那么你是看不到我标题中的汉字的,显示为一个小方框,但是你使用edge查看的话,这个字就能正常的显示出来,不信你试试! 本故事源于我在做数据过程中遇到Unicode编码 ...

  8. Binary String Copying

    Smiling & Weeping ----第一次见你的时候, 在我的心里已经炸成了烟花, 需要用一生来打扫灰炉. 题目链接:Problem - C - Codeforces 题目大意不难,就 ...

  9. jdk8环境变量

    JAVA_HOME C:\Program Files\Java\jdk1.8.0_333 Path%JAVA_HOME%\bin%JAVA_HOME%\jre\bin CLASSPATH.%JAVA_ ...

  10. Java新特性中的Preview功能如何运行和调试

    在每个Java新版本发布的特性中,都会包含一些Preview(预览)功能,这些功能主要用来给开发者体验并收集建议.所以,Preview阶段的功能并不是默认开启的. 如果想体验某个Java版本中的Pre ...