V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
choice4
V2EX  ›  Java

Java 为什么会这样

  •  
  •   choice4 · 2018-12-13 19:48:42 +08:00 · 3638 次点击
    这是一个创建于 2174 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ![]( )
    第 1 条附言  ·  2018-12-13 21:01:26 +08:00
    是没人知道,还是这是正常现象
    16 条回复    2018-12-14 12:25:06 +08:00
    choice4
        1
    choice4  
    OP
       2018-12-13 19:51:29 +08:00
    坐标 java.io.OutputStream
    jdk8 中是 1108 行
    方法是
    private void writeObject0(Object obj, boolean unshared) throws IOException
    choice4
        2
    choice4  
    OP
       2018-12-13 19:51:55 +08:00
    错了 是 java.io.ObjectOutputStream
    misaka19000
        3
    misaka19000  
       2018-12-13 21:38:55 +08:00 via Android
    jvm 是不认布尔类型的,编译器会把 bool 转为 byte
    choice4
        4
    choice4  
    OP
       2018-12-13 21:45:54 +08:00 via Android
    @misaka19000 为什么自己代码里的 boolean 就可以计算出布尔呢
    leido
        5
    leido  
       2018-12-13 22:37:11 +08:00 via Android
    整数运算是最快的,java 在硬件层面搞个 bool 计算得不偿失
    szq8014
        6
    szq8014  
       2018-12-14 08:59:44 +08:00
    @misaka19000 +1
    不怀疑一下你使用的工具吗?真想看值打印出来最好。
    可能是 IDE 没推出正确的类型,只知道是 0x01 了,不知道是该转成 bool, byte, short, int 中的哪个?
    choice4
        7
    choice4  
    OP
       2018-12-14 09:23:47 +08:00 via Android
    @szq8014 这个是 jdk 里面的中间值我打印不出来。我点进那个方法里面跟到 return 部分是对一个布尔类型取非 那个布尔是 false. 也就是 return !false;. 但是 boolean 接收到的返回值是个 1。开源中国上有人在 BigDecimal 中发现过这个问题,但是底下评论好像也没说出个一二三来。
    szq8014
        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
    szq8014
        9
    szq8014  
       2018-12-14 09:59:57 +08:00
    说错了一些…… NameAndType 是方法描述, 变量是在 constant pool 里有对应的类型和名称,上面 [应该是] 给优化成了匿名变量,我没在 javap 导出的内容里面找到 oldMode 相关字样 0.0
    DonaldY
        10
    DonaldY  
       2018-12-14 10:12:40 +08:00
    在讨论 boolean 为什么会是 0 和 1 ?

    这不是常识?
    choice4
        11
    choice4  
    OP
       2018-12-14 10:21:58 +08:00
    @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
    szq8014
        12
    szq8014  
       2018-12-14 10:40:14 +08:00
    @DonaldY 大神,请问下为什么分析工具没正确把 1 解析成 true,有没有这块相关的常识可以分享一下
    lurenw
        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/
    szq8014
        14
    szq8014  
       2018-12-14 11:01:43 +08:00
    @lurenw 学到了! thx
    choice4
        15
    choice4  
    OP
       2018-12-14 11:20:16 +08:00
    @lurenw 3q
    xzy
        16
    xzy  
       2018-12-14 12:25:06 +08:00
    JVM boolean 就是一个整数,Unsafe.putBoolean 其实就是 x&1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4697 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 09:57 · PVG 17:57 · LAX 01:57 · JFK 04:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.