Java 为什么会这样 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
choice4
V2EX    Java

Java 为什么会这样

  •  
  •   choice4 2018-12-13 19:48:42 +08:00 3855 次点击
    这是一个创建于 2495 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ![]( )
    第 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     Solana     5468 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 42ms UTC 01:25 PVG 09:25 LAX 18:25 JFK 21:25
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86