Когда я должен использовать ключевое слово 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();
ArrayList contactList = 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”