#java #lambda #anonymous
#java #лямбда #Аноним
Вопрос:
У меня есть вопрос об анонимном объекте в Java.
Если я создам статический метод ( name = go()
), который имеет один анонимный объект, и этот анонимный объект использует локальную переменную go()
.
Я знаю, что локальная переменная, которая используется для анонимного объекта, должна быть объявлена как final
.
И затем final variable(numberCnt)
выполняется в области стека вместо области кучи.
Область стека не является целью GC.
если я вызываю 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);
}
}
Ответ №1:
Анонимный класс копирует значения переменных, которые он фиксирует в момент создания объекта анонимного класса. Итак, в основном ваш анонимный класс имеет скрытую int
переменную экземпляра для ее захвата numberCnt
, и вы можете представить, что за кулисами компилятор в основном переходит numberCnt
в скрытый «конструктор» вашего анонимного класса для инициализации этой скрытой переменной экземпляра. При возврате функции фрейм стека go
исчезает, и в стеке никогда не бывает более 1 фрейма стека для go
. Вы просто получаете множество экземпляров вашего анонимного класса в куче, и каждый из этих экземпляров имеет int
переменную экземпляра с другим значением.
Комментарии:
1. Спасибо за ваш ответ. Вы имеете в виду, что мне не нужно беспокоиться о стеке над потоком, потому что анонимный объект будет удален после использования в go(). Верно??
2. @Thecaptinofsixcanon: На объект ссылается исполнитель, и он будет собран после того, как исполнитель его выполнит.