Когда сделал метод add () добавить объект в коллекцию - PullRequest
0 голосов
/ 07 октября 2018

У меня два вопроса.Во-первых, рассмотрим приведенный ниже код.

public class Test{
    private static final List<String> var = new ArrayList<String>() {{
        add("A");
        add("B");
        System.out.println("INNER : " + var);
    }};

    public static void main(String... args){
        System.out.println("OUTER : " + var);
    }   
}

Когда я запускаю этот код, он дает мне вывод ниже

INNER : null
OUTER : [A, B]

Может ли кто-нибудь уточнить, почему INNER равен нулю и поток выполнения привремя, когда ровно «A» и «B» добавляются к collection?

Во-вторых, я внес некоторые изменения в приведенный выше код и изменил его до значения ниже единицы (просто поместите метод add в первую скобку)

public class Test{
    private static final List<String> var = new ArrayList<String>() {
        public boolean add(String e) { 
            add("A");
            add("B");
            System.out.println("INNER : " + var); return true; 
        };
    };

    public static void main(String... args){
        System.out.println("OUTER : "+var);
    }   
}

После запуска кода выше я получил результат ниже

OUTER : []

После просмотра я совершенно не понимаю, что происходит.Куда ушел INNER?Почему это не печать?Разве это не называется?

Ответы [ 4 ]

0 голосов
/ 07 октября 2018

В первом коде вы печатаете переменную до того, как ее конструктор вернулся, когда вы добавляете элементы и печатаете список внутри инициализатора экземпляра.Так что можно печатать только null.

Во втором коде вы переопределяете add() для добавления жестко закодированных элементов, но add() никогда не вызывается в созданном экземпляре.Так что add() ничего не печатает и ничего не добавляется в экземпляр List.

Чтобы добавить элементы в список, который вы обычно хотите вызвать add() в ссылке на Список, например:

List<String> list = new ArrayList<>();
list.add("element A");
list.add("element B");

Вы не создаете анонимный класс для такого требования.

Если вы хотите использовать более простой синтаксис, вы все равно можете сделать:

List<String> list = new ArrayList<>(Arrays.asList("element A", "element B"));
0 голосов
/ 07 октября 2018

В вашем фрагменте кода 1 вы используете инициализацию двойной скобкой для добавления элементов в список массивов.Это в основном анонимный внутренний класс с инициализатором экземпляра.Поскольку вы печатаете var до создания объекта, это null.

Во втором фрагменте вы создаете анонимный класс ArrayList, обеспечивающий реализацию метода add.Но никто не вызывает метод add для объекта ArrayList.

РЕДАКТИРОВАТЬ: Хорошая точка зрения Andreas @ - Даже если вы вызываете метод add, онприведет к бесконечному рекурсивному вызову, что приведет к StackOverflowError.

Ссылка:

Инициализация ArrayList в одну строку

0 голосов
/ 07 октября 2018
  1. Созданный вами объект не был присвоен var в процедуре инициализации, попробуйте это:

    private static final List<String> var = new ArrayList<String>() {{
        add("A");
        add("B");
        System.out.println("THIS : " + this); // THIS : [A, B]
        System.out.println("INNER : " + var); // INNER : null
    }};
    
  2. Вы просто переопределите addметод ArrayList, его никогда не называли.Это работает как:

    static class CustomList<E> extends ArrayList<E> {
    
        @Override
        public boolean add(String e) {
            add("A");
            add("B");
            System.out.println("INNER : " + var);
            return true;
        }
    }
    
    private static final List<String> var = new CustomList<>();
    
0 голосов
/ 07 октября 2018
  1. Поскольку блок инициализатора анонимного класса выключен ArrayList выполняется до , ссылка на экземпляр анонимного класса присваивается var.

  2. Код не выполняется, потому что вы никогда не вызываете метод add(String e).Если бы вы это сделали, это привело бы к StackOverflowError, поскольку add("A") теперь является рекурсивным вызовом.

...