V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
alexanderchiu
V2EX  ›  问与答

Java 大佬们进来看看?我在阅读 LinkedHashMap 源码的时候发现的一个小问题!可能是 dead code?

  •  
  •   alexanderchiu · 2020-05-06 19:28:35 +08:00 · 1537 次点击
    这是一个创建于 1661 天前的主题,其中的信息可能已经有所发展或是发生改变。

    JDK 版本 11

    是这样的,LinkedHashMap 不是用一个双向链表来维护所有插入元素的顺序嘛? 它有一个成员accessOrder

    final boolean accessOrder;
    

    默认为 false,如果设为 true 的话,每次进行get操作的时候呢,都会把操作得到的元素移动到链表的末尾。也就是afterNodeAccess这个方法干的事情

    // 访问结点 e 之后,如果结点 e 不在表尾,则会将其移动到表尾(该项功能默认是关闭的,由 accessOrder 负责开启)
        void afterNodeAccess(Node<K, V> e) {
            LinkedHashMap.Entry<K, V> last;
            
            if(accessOrder && (last = tail) != e) {
                //如果能进入到 if 语句,说明 e 不是双向链表的末尾,那么 a 作为 p(e 强转为 Entry 为 p)的后继不可能为 null 对吧?
                //如果不能进入 if 语句,说明 e 就是双向链表的末尾,我们不需要做任何操作
                LinkedHashMap.Entry<K, V> p = (LinkedHashMap.Entry<K, V>) e, b = p.before, a = p.after;
                
                p.after = null;
                
                if(b == null) {
                    head = a;
                } else {
                    b.after = a;
                }
    
                // 那么既然 a 不可能为 null,这个判断是否多余?这里的 if else 是否多余?
                if(a != null) {
                    a.before = b;
                } else {
                    last = b;
                }
                
                if(last == null) {
                    head = p;
                } else {
                    p.before = last;
                    last.after = p;
                }
                
                tail = p;
                
                ++modCount;
            }
        }
    

    问题来了,如果能够进入大的那个 if 嵌套语句,说明结点 e 不可能是链表末尾结点因为 (last=tail)!=e 那么引用 a 作为 p 的后继节点(p 为 e 强制类型转换后),不可能为 null 对吧?因为只有 e 为链表末尾结点的时候,其后继才会为 null,如果不是链表末尾结点,后继肯定不是 null

    那么下面的这个 if else 语句是否多余了? a 一定不会为 null,else 语句貌似永远不能执行?

     // 那么既然 a 不可能为 null,这个判断是否多余?这里的 if else 是否多余?
         if(a != null) {
         	a.before = b;
         } else {
        	 last = b;
         }
    

    然后我自己尝试打断点做实验,发现好像怎么也走不到 else 那个语句...

    3 条回复    2020-05-06 21:10:50 +08:00
    zidian9
        1
    zidian9  
       2020-05-06 20:00:28 +08:00
    多线程情况下可以走到这个里面吧
    alexanderchiu
        2
    alexanderchiu  
    OP
       2020-05-06 20:07:13 +08:00
    @zidian9 有道理...我傻了 可能是别的线程使得 a 变成 null
    beidounanxizi
        3
    beidounanxizi  
       2020-05-06 21:10:50 +08:00
    你好可爱
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2304 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:04 · PVG 00:04 · LAX 08:04 · JFK 11:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.