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 5
因为 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
|