Рубрики
Без рубрики

Ключевое слово Java ‘Static’ – Вступление: Как (не) его использовать

Когда я должен использовать ключевое слово static? Что он делает? Не имеет значения, ИДЕЯ в том, чтобы подсказать мне, что добавить… Помеченный java.

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