Если анонимный объект использует локальную переменную внешнего метода infinity, это может быть переполнение стека или нет?

#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: На объект ссылается исполнитель, и он будет собран после того, как исполнитель его выполнит.