yukiloh
V2EX  ›  Java

被 jvm 编译器蠢哭了

  •  
  •   yukiloh · May 24, 2020 · 4503 views
    This topic created in 2361 days ago, the information mentioned may be changed or developed.
        private void myTest(boolean isNeeded) {
            //业务需求:遍历一个 list 的过程中,如果 isNeeded 为 true,则为 neededList 插入数据
            // ↓为编译器错误,
            // ArrayList<Integer> neededList = null;
            // if (isNeeded) neededList = new ArrayList<>();
    		
            // ↓通过检查
            ArrayList<Integer> neededList = new ArrayList<>();
    
    
            ArrayList<String> list = new ArrayList<>();
            //...处理其他业务
            list.forEach(element -> {
                //...处理其他业务
                if (isNeeded) neededList.add(1);
            });
        }
    

    为啥他就感知不到 false 的情况不会执行呢...

    14 replies  •  2020-05-24 23:19:57 +08:00
    wwqgtxx
    wwqgtxx
    May 24, 2020 via iPhone
    1
    java 中 lamdba 表达式捕获的变量需要隐式的为 final 类型的吧
    fewok
    fewok
    May 24, 2020
    2
    list 插条数据呗,你这例子,list 是空数组,怎么可能会执行 foreach 里的内容呢?
    w292614191
    w292614191
    May 24, 2020
    3
    哈哈哈哈哈哈哈哈,是你故意这样写的,还是我太菜了。
    chendy
    chendy
    May 24, 2020
    4
    Variable used in lambda expression should be final or effectively final
    Aresxue
    Aresxue
    May 24, 2020❤️4
    5
    lambda 里面的变量需要是 final 的, 使用的变量被隐式转为了 final, 编译器报错不是因为不会推断,而是你在给一个 final 变量重新赋值,手动加上 final 你就会知道真正的报错是在 neededList = new ArrayList<>(); 这里
    Liyiw
    Liyiw
    May 24, 2020
    6
    不是太懂这个描述。。
    Liyiw
    Liyiw
    May 24, 2020
    7
    @Aresxue 说的给一个 final 变量重新赋值是在哪里
    yukiloh
    yukiloh
    OP
    May 24, 2020
    8
    @Aresxue 明白了,原来会隐式添加 final.我想省那么点内存,判断需要了再去 new...
    yousabuk
    yousabuk
    May 24, 2020 via iPhone
    9
    jvm 编译器被谁蠢哭了呢
    EscYezi
    EscYezi
    May 24, 2020 via iPhone
    10
    @Liyiw needList 初始值是 null,接着 if 里面又给 needList 赋值了新的对象;像#5 所说的,needList 被编译器增加了 final,这样做是在给 final 变量重新赋值
    Liyiw
    Liyiw
    May 24, 2020
    11
    @EscYezi 谢谢,搞懂了
    webbon
    webbon
    May 24, 2020 via Android❤️2
    12
    @yousabuk #1 和#5 会解释这是隐式 final,而不是嘲讽别人这都不懂
    HeapOverflow
    HeapOverflow
    May 24, 2020 via iPhone
    13
    是 JVM 被你蠢哭了
    Kaiv2
    Kaiv2
    May 24, 2020 via Android❤️1
    14
    明白你的意思了,个人理解: lamdba 表达式可以存在变量里,使用外部可变引用可能会增加复杂性。这里的例子如果在 forEach 中将 neededList 指向新的对象了,外部变量是否也修改呢?
    如果只是使用 forEach 遍历建议修改为 for 迭代器模式,可以解决这个问题。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4044 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 54ms · UTC 05:46 · PVG 13:46 · LAX 21:46 · JFK 00:46
    ♥ Do have faith in what you're doing.