#java #collections
Вопрос:
Я случайно написал этот код и обнаружил ошибки:
class Main {
LinkedList<Integer> list = new LinkedList<>();
list.add(10);
list.add(5);
public static void main(String[] args) {
Main myObj = new Main();
System.out.prinln(myObj.list);
}
}
Если я объявляю LinkedList статическим и заполняю его статическим блоком, ошибки нет, или если я создаю метод, а затем заполняю список внутри метода, то также ошибки нет.
Я новичок и не могу понять причину, по которой он не заполняется, когда я пытаюсь, как в приведенном выше коде. Пожалуйста, объясните это как для 1-го стандартного студента. Спасибо!
Комментарии:
1. Вы хотите, чтобы он был заполнен при
Main
создании объекта (new Main()
)? если это так, добавьте эти строки в конструктор .
Ответ №1:
… причина, по которой он не заполняется, когда я пытаюсь, как в приведенном выше коде.
Потому что язык Java был разработан таким образом. list.add(10)
это вызов метода, и существуют ограничения на то, где разрешены вызовы методов. Было бы вполне возможно разработать язык, который позволял бы вызовы методов (и другие операторы) чередоваться с объявлениями в классе. Однако я не видел этого ни на одном языке. В конце концов, это также может привести к путанице.
Позвольте два предложения:
- Подумайте дважды, прежде чем использовать a
LinkedList
. - Заполните свой список в декларации.
За свои 20 с лишним лет работы Java-программистом я однажды использовал a LinkedList
и, оглядываясь назад, пожалел об этом. У этого класса так мало хороших применений. ArrayList
почти всегда будет более эффективным с точки зрения времени и пространства.
Начиная с Java 9, вы можете объявлять и заполнять список таким образом, если его не нужно изменять:
List<Integer> list = List.of(10, 5);
Если вам понадобится возможность изменить список позже:
List<Integer> list = new ArrayList<Integer>(List.of(10, 5));
Кстати , то же самое работает и для LinkedList
. В Java 8 и более ранних версиях вы можете использовать Arrays.asList()
, например:
List<Integer> list = new ArrayList<Integer>(Arrays.asList(10, 5));
Ответ №2:
Если мы разберем приведенный выше код, он будет состоять из class
именованного «Основного», содержащего:
variable
Именованный «список» типа LinkedList- Заявление
list.add(10);
- Еще одно заявление
list.add(5);
- Метод с именем «main», содержащий еще 2 оператора.
A class
в java-это языковая конструкция, которой разрешено иметь определенные типы членов.
Спецификации java сообщают нам, какие члены класса могут иметь:
В теле класса объявляются члены (поля, методы, классы и интерфейсы), инициализаторы экземпляров и статические инициализаторы, а также конструкторы
https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.2
Проблема с приведенным выше кодом заключается в том, что операторы не могут быть членами класса. Компилятор отклонит их.
Java, однако, предоставляет нам инструмент для заполнения коллекции вне метода. Это статические инициализаторы
Редактировать: Спасибо @Ole V. V. и @fps за то, что поправили меня здесь
Это инициализатор экземпляра
Инициализатор экземпляра, объявленный в классе, выполняется при создании экземпляра класса
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.6
Применительно к приведенному выше коду мы можем написать:
import java.util.LinkedList;
class Main {
LinkedList<Integer> list = new LinkedList<>();
{ // This bracket starts the initializer
list.add(10);
list.add(5);
} // This bracket closes the initializer
public static void main(String[] args) {
Main myObj = new Main();
System.out.println(myObj.list);
}
}
Надеюсь, это немного поможет 🙂
Комментарии:
1. Это инициализатор экземпляра, как говорит @OleV.V.. Статические инициализаторы используются для инициализации переменных класса, а переменная класса является статической переменной, переменная класса-это просто еще один способ вызова статической переменной. Инициализаторы экземпляра, с другой стороны, полезны для инициализации полей экземпляра, таких как связанный список вопроса (т. е. нестатические члены).
2. Помимо этой небольшой путаницы в отношении статических и нестатических инициализаторов, ваш ответ превосходен
3. О, я все это время ошибался 🙂 Спасибо обоим за разъяснение этого!