1 choice4 OP 坐标 java.io.OutputStream jdk8 中是 1108 行 方法是 private void writeObject0(Object obj, boolean unshared) throws IOException |
2 choice4 OP 错了 是 java.io.ObjectOutputStream |
![]() | 3 misaka19000 2018-12-13 21:38:55 +08:00 via Android jvm 是不认布尔类型的,编译器会把 bool 转为 byte |
4 choice4 OP @misaka19000 为什么自己代码里的 boolean 就可以计算出布尔呢 |
5 leido 2018-12-13 22:37:11 +08:00 via Android 整数运算是最快的,java 在硬件层面搞个 bool 计算得不偿失 |
![]() | 6 szq8014 2018-12-14 08:59:44 +08:00 @misaka19000 +1 不怀疑一下你使用的工具吗?真想看值打印出来最好。 可能是 IDE 没推出正确的类型,只知道是 0x01 了,不知道是该转成 bool, byte, short, int 中的哪个? |
7 choice4 OP @szq8014 这个是 jdk 里面的中间值我打印不出来。我点进那个方法里面跟到 return 部分是对一个布尔类型取非 那个布尔是 false. 也就是 return !false;. 但是 boolean 接收到的返回值是个 1。开源中国上有人在 BigDecimal 中发现过这个问题,但是底下评论好像也没说出个一二三来。 |
![]() | 8 szq8014 2018-12-14 09:38:26 +08:00 ![]() 我自己打断点看也是显示为数值 0 或 1,然后图中显示变量在 slot_3 中。 javap 那个 `javap -verbose -p ObjectOutputStream.class >> out` 里面显示 ` private void writeObject0(java.lang.Object, boolean) throws java.io.IOException; descriptor: (Ljava/lang/Object;Z)V flags: ACC_PRIVATE Code: stack=4, locals=10, args_size=3 0: aload_0 1: getfield #538 // Field bout:Ljava/io/ObjectOutputStream$BlockDataOutputStream; 4: iconst_0 5: invokevirtual #601 // Method java/io/ObjectOutputStream$BlockDataOutputStream.setBlockDataMode:(Z)Z 8: istore_3 9: aload_0 10: dup 11: getfield #532 // Field depth:I 14: iconst_1 15: iadd 16: putfield #532 // Field depth:I 19: aload_0 20: getfield #542 // Field subs:Ljava/io/ObjectOutputStream$ReplaceTable; 23: aload_1 24: invokevirtual #630 // Method java/io/ObjectOutputStream$ReplaceTable.lookup:(Ljava/lang/Object;)Ljava/lang/Object; 27: dup ` 哎呀,JVM 知识不够用了,到第 8 行看起来应该是根本没有 getfield oldMode 相关的字样,也就是直接在栈桢上就操作完了,给优化成了匿名变量了 0.0 ?找不到对应的 NameAndType ?如果是这样的话 IDE 怎么知道 oldMode 在 slot_3 的? 有没有大神愿意出来讲讲 0.0 |
![]() | 9 szq8014 2018-12-14 09:59:57 +08:00 说错了一些…… NameAndType 是方法描述, 变量是在 constant pool 里有对应的类型和名称,上面 [应该是] 给优化成了匿名变量,我没在 javap 导出的内容里面找到 oldMode 相关字样 0.0 |
![]() | 10 DonaldY 2018-12-14 10:12:40 +08:00 在讨论 boolean 为什么会是 0 和 1 ? 这不是常识? |
11 choice4 OP @szq8014 执行表达式执行 System.out.println(oldMode) 抛出了 com.sun.jdi.VMMismatchException : 1 Oracle Docs 中 public class VMMismatchException extends RuntimeException Thrown to indicate that the requested operation cannot be completed because the a mirror from one target VM is being combined with a mirror from another target VM. Since: 1.3 |
![]() | 13 lurenw 2018-12-14 10:52:39 +08:00 ![]() 因为 jdk 的 classes 是不携带 local variable 的 debug info,所以 idea 在 debug 到这些类的时候,只能靠 slot 上的值和 variable map 对应起来进行猜测。 这是 idea 的特性 https://blog.jetbrains.com/idea/2013/10/show-local-variables-in-debugger-even-with-no-debug-info/ |
16 xzy 2018-12-14 12:25:06 +08:00 JVM boolean 就是一个整数,Unsafe.putBoolean 其实就是 x&1 |