Когда я должен использовать ключевое слово static? Что он делает? Не имеет значения, среда разработки говорит мне, куда ее добавить!
С таким отношением мой основной класс в итоге выглядел так:
Пример 1
public class Main { static Contact contact = new Contact(); static Input input = new Input(); public static void main(String[] args) { showMenu(); } public static void showMenu() { int menuChoice; menuChoice = input.menuChoice(); switch (menuChoice) { case 1: updateContact(); default: break; } } static void updateContact() { updateContactFields(); showContact(); } static void updateContactFields() { // lots of update calls } static void showContact() { // Lots of prints showMenu(); } }
Это было крушение поезда по многим причинам, но статика всего вызывала проблемы, о которых я не знал.
Плохой ход, Джулс
У меня были приоритеты, и выяснение того, что означали все эти (не очень) общие ключевые слова, было низким. В любом случае, программа работала, и если я создал новый метод, IntelliJ сказал мне, что я не могу ссылаться на нестатический метод из статического контекста, поэтому все методы стали статическими.
Однако в глубине души меня что-то беспокоило;
- Основной метод в классе Java должен быть статическим
- Каждый метод, который я использовал, прямо или косвенно вызывался через основной метод
- Методы, вызываемые другими классами, не обязательно должны быть статическими, но также могут быть
Так почему же я все время это добавлял?
Блокировщик
В конце концов, сочетание использования рекурсии, где циклы были лучше, и создание статики всего моего класса вызвало проблемы с состоянием, которые я не мог отладить. Кто-то, знакомый с Java, бросил быстрый взгляд и спросил меня, знаю ли я, что делает статика.
Они описали это в терминах Ruby как превращение чего-либо в метод класса или переменную. Мне нужен был пример в лучшем случае, но я непреднамеренно сделал все глобальным.
Решение/Пример 2
public class Main { Input input = new Input(); ArrayListcontactList = new ArrayList<>(); public static void main(String[] args) { Main main = new Main(); main.showMenu(); } public void showMenu() { boolean complete = false; while (!complete) { printMenuOptions(); int userInput = input.menuChoice(); switch (userInput) { case 1: { newContact(); break; } case 2: { updateExistingContact(); break; } case 3: { showContact(); break; } default: complete = true; break; } } } void printMenuOptions() { // logs } void newContact() { contactList.add(new Contact(input.confirmInput("first name"), input.confirmInput("last name"), input.confirmInput("address"), input.confirmInput("phone number"), input.confirmInput("DOB in dd/mm/yyyy format"), input.confirmInput("email"))); } void updateExistingContact() { if (checkForContacts()) { displayContacts(); try { updateContactFields(contactList.get(Integer.parseInt(input.confirmInput("contact choice")) - 1)); } catch (Exception e) { System.out.println("No such contact"); } } } boolean checkForContacts() { if (contactList.size() == 0) { System.out.println("There are no contacts yet"); return false; } else { return true; } } void updateContactFields(Contact contact) { // logs and update calls } void showContact() { if (checkForContacts()) { displayContacts(); Contact contact = null; try { contact = contactList.get(input.contactChoice() - 1); } catch (Exception e) { System.out.println("No such contact"); showMenu(); } printContactDetails(contact); } } void printContactDetails(Contact contact) { // lots of logs } void displayContacts() { System.out.println("Please select a contact"); for (int i = 0; i < contactList.size(); i++) { System.out.println(i + 1); } } }
(Примечание: здесь тоже есть дополнительная функциональность)
Чтобы избежать вызова методов из статического метода main
, вы просто:
- Создайте экземпляр основного класса в методе main
- Вызывайте любые методы из этого экземпляра Main (например, main.отображать контакты())
- Теперь вам нужно только сделать вещи статичными там, где это хорошая практика
Когда все должно быть статичным?
Я рад, что вы спросили: Допустим, у меня есть список контактов, и каждый из этих контактов имеет несколько свойств. В случае, если они имеют общее свойство, переменная может быть статической для экономии памяти.
class Contact { String name; static String country = "Arstotzka"; int age; // and so on }
Если у меня есть 10 экземпляров контактов, переменной name
будет назначена память 10 раз. С другой стороны, страна
статична, поэтому ей предоставляется память только один раз, сколько бы экземпляров ни было. Это не обязательно должно быть статичным, но это более эффективно, с точки зрения памяти, чтобы сделать это так.
Записи:
- Его все еще можно изменить, но вероятность его изменения меньше, чем у нестатических переменных.
- Статические переменные также должны быть инициализированы значением, так как вы говорите, что переменная и ее значение присущи классу.
Методы класса
Методы класса используются без создания экземпляра класса, как это было в примере 1. Main никогда не создавался, поэтому, если я вызывал какие-либо методы, они должны были быть на уровне класса, а не на уровне объекта.
Пример 3
class Contact { String name; static String country = "Arstotzka"; int age; // and so on static void updateCountry() { country = "Republia"; } }
Статический метод в примере 3 обновляет статическую переменную страна
, поэтому каждый экземпляр контакта теперь будет иметь строковое значение “Republia” вместо “Arstotzka”.
Резюмировать
- Статические переменные являются переменными уровня класса, поэтому наследуются экземплярами и должны быть инициализированы перед созданием экземпляра
- Статические методы являются методами класса и вызываются без класса создается экземпляр
- Если вы хотите использовать методы экземпляра, вам необходимо создать экземпляр своего класса (только что установлена связь между переменными/методами экземпляра и экземплярами классов)
Это далеко не исчерпывающая информация, но это информация, которая сэкономила бы мне много времени и боли, если бы я провел исследование раньше.
Дайте мне знать ваши мысли, считаете ли вы, что это ясно и полезно, или я упустил что-то важное и сделал несколько неверных утверждений!
Оригинал: “https://dev.to/jimjule/java-static-keyword-how-not-to-use-it-as-a-beginner-134l”