在java consumer callback中,在callback方法中引用的final变量会发生什么?

vfh0ocws  于 2023-08-01  发布在  Java
关注(0)|答案(1)|浏览(105)

这里的数据变量什么时候可以进行垃圾回收?以及JVM如何知道这个数据变量必须是活的,因为我的任务是活的。我的编辑唯一说的是变量需要是final或有效的final。好吧,我不会更新它,但仍然将如何参考结转?java也有类似JavaScript的闭包的概念吗?或者它是什么进程?我要求任何官方的JVM规范文档或任何可信的来源,我可以得到关于在这种情况下到底发生了什么的信息。

public void schedule() {
        String data = "adfasdf";
        scheduler.newJob("bussinessruleid")
                 .setCron("0/5 * * * * ?")
                 .setTask(executionContext -> {
                    System.out.println(executionContext + " " + data);
                }).schedule();
    }

字符串

gg0vcinb

gg0vcinb1#

只要scheduler.newJob()调度的任务处于活动状态,data变量就会保持活动状态,因为任务的回调函数会捕获数据,防止其被垃圾收集。
你可以把例子中的数据变量看作是你提供给setTask()的匿名函数“捕获”的。这里,“捕获”意味着即使在schedule()返回之后,函数也保留对数据的引用。
只要函数本身是活动的,匿名函数就保持数据变量是活动的。在您的例子中,只要您创建的计划任务仍然存在,数据就没有资格进行垃圾收集,因为它仍然被引用。
JVM知道保持数据的活动性,因为它看到函数已经捕获了数据,因此维护了对它的引用。这不是Java独有的;这是许多支持闭包的编程语言中的一个常见特性。
当代码运行schedule()时,该方法将完成,在正常情况下,当该方法返回时,像数据这样的局部变量将有资格进行垃圾收集。但是由于匿名函数捕获数据,并且函数本身由调度程序保持活动状态,因此JVM知道将数据保存在内存中。
"final"意味着变量的值在赋值后不能改变。它本质上与final相同,但没有显式的final修饰符。Java 8中引入它是为了在使用lambda表达式和匿名类时给予更大的灵活性,匿名类只能从外部作用域访问final或有效的final变量。

相关问题