英文:
If anonymous object use the local variable of external method infinity, it can be stack overflow or not?
问题
以下是你提供的内容的翻译:
关于 Java 中的匿名对象,我有一个问题。
如果我创建一个静态方法(name = go()
),该方法拥有一个匿名对象,并且这个匿名对象使用了 go()
方法的局部变量。
我知道,用于匿名对象的局部变量必须声明为 final
。
然后,final
变量(numberCnt
)在堆栈区域创建,而不是在堆区域。
堆栈区域不是垃圾回收的目标。
如果我无限地调用 go()
,是否会导致堆栈溢出错误?
以下是我的问题来源。
package com;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestMain {
public static void main(String[] args) {
int i = 0;
while (true) {
i++;
go(i);
try {
Thread.sleep(1000);
} catch (Exception e) {
}
if (i > 10_000_000) {
i = 0;
}
}
}
private static void go(int i) {
int numberCnt = i;
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
String rtnValue = "Number=>" + numberCnt;
System.out.println("Number=>" + rtnValue);
return rtnValue;
};
};
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(callable);
}
}
英文:
I have a question about anonymous object in Java.
If I make a static method(name = go()
) which has one anonymous object and this anonymous object uses the local variable of go()
.
I know that local variable which is used for anonymous object has to be declared to be final
.
And then final variable(numberCnt)
is made in stack area instead of heap area.
The stack area is not target of GC.
if I call go()
infinitely, will stack overflow occur or not?
The below is my question source.
package com;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestMain {
public static void main(String[] args) {
int i =0;
while(true) {
i++;
go(i);
try {
Thread.sleep(1000);
} catch (Exception e) {
}
if(i > 10_000_000) {
i=0;
}
}
}
private static void go(int i) {
int numberCnt = i;
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
String rtnValue = "Number=>" + numberCnt;
System.out.println("Number=>" + rtnValue);
return rtnValue;
};
};
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(callable);
}
}
答案1
得分: 2
这个匿名类在创建匿名类对象的时刻复制了它所捕获的变量的值。所以基本上你的匿名类有一个隐藏的 int
实例变量来捕获 numberCnt
,你可以想象,在幕后,编译器基本上会将 numberCnt
传递到匿名类的隐藏“构造函数”中,以初始化这个隐藏的实例变量。当函数返回时,go
的栈帧已经消失了,在堆栈上永远不会有超过 1 个 go
的栈帧。你只会在堆上得到许多匿名类的实例,每个实例都有一个不同值的 int
实例变量。
英文:
The anonymous class copies the value of the variables it captures at the moment the anonymous class object is created. So basically your anonymous class has a hidden int
instance variable for its capture of numberCnt
, and you can imagine, behind the scenes, the compiler basically passes numberCnt
into the hidden "constructor" of your anonymous class to initialize this hidden instance variable. The stack frame of go
is gone when the function returns, and there is never more than 1 stack frame for go
on the stack. You just get lots of instances of your anonymous class on the heap, and each of those instances has an int
instance variable with a different value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论