You've successfully subscribed to Заметки Разработчиков
Great! Next, complete checkout for full access to Заметки Разработчиков
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.

code

Модификаторы доступа в Java

Коротко о существующих модификаторах доступа: public, protected, default, private.

private (приватный): члены класса доступны только внутри класса. Для обозначения используется служебное слово private.

default, package-private (доступ на уровне пакета): видимость класса/членов класса только внутри пакета. Является модификатором доступа по умолчанию - специальное обозначение не требуется.

protected (защищённый): члены класса доступны внутри пакета и в наследниках. Для обозначения используется служебное слово protected.

public (публичный): класс/члены класса доступны всем. Для обозначения используется служебное слово public.

Последовательность модификаторов от самого открытого до самого закрытого: public, protected, default, private.

Визуально модификаторы доступа переменной класса можно представить таким образом:

Подробнее про все существующие модификаторы читайте в этой статье 👇

Обзор всех модификаторов в Java
Модификаторы это ключевые слова в Java, которые ”изменяют и регулируют” работу классов, методов и переменных.

Слишком специфичные исключения

В некоторых проектах джунов иногда вижу довольно сильный упор на узко-направленные исключения. Например: public class UserNotFoundException extends RuntimeException { public UserNotFoundException(String message) { super(message); } } public class EventNotFoundException extends RuntimeException { public EventNotFoundException(String message) { super(message); } } И так далее, сколько сущностей, столько и исключений. Но поведение у них у всех одно.

В некоторых проектах джунов иногда вижу довольно сильный упор на узко-направленные исключения. Например:

public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}
public class EventNotFoundException extends RuntimeException {
    public EventNotFoundException(String message) {
        super(message);
    }
}

И так далее, сколько сущностей, столько и исключений. Но поведение у них у всех одно. Поэтому зачем их плодить?

Достаточно создать одно исключение NotFoundException и использовать его:

public class NotFoundException extends RuntimeException {
    public NotFoundException(String message) {
        super(message);
    }
}

Создавайте самостоятельное исключение, только если предпологается его какая-то особенная обработка, или если существующие исключения вам не подходят. Например, странно бросать NotFoundException, если ситуация будет связана с проблемами доступа. Тогда лучше создать какой-нибудь AccessException.

Сравнение enum в Java

Enum это объект, как и все в Java. Однако это особенный объект. Каждый из объектов енума создаётся только единожды. Давайте на примере: enum TestEnum {ONE, TWO, THREE} Если мы создадим 10 переменных TestEnum.ONE, то все они будут ссылаться на один и тот же объект. И поэтому enum можно сравнивать

Enum это объект, как и все в Java. Однако это особенный объект. Каждый из объектов енума создаётся только единожды. Давайте на примере:

enum TestEnum {ONE, TWO, THREE}

Если мы создадим 10 переменных TestEnum.ONE, то все они будут ссылаться на один и тот же объект. И поэтому enum можно сравнивать с помощью == и это корректно и будет работать.

Сторонники такого подхода называют следующие преимущества. Давайте их разберем.

Вы никогда не получите NullPointerException. И это правда, но если вы будете придерживаться правила "Сравнение константы слева", то и при использовании .equals() NullPointerException вам не страшен.

Оператор == работает быстрее. Быстрее чего? Видимо метода .equals(). Давайте посмотрим реализацию метода .equals() у enum.

Оператор == более понятный синтаксически. Это еще почему? Для сравнения объектов в Java используется .equals(). Enum это объект. Логичнее и очевиднее использовать .equals() для сравнения, чтобы не нарушать единообразие сравнения объектов.

На мой взгляд, правильнее использовать .equals(), главное не забывать о правиле "Сравнение константы слева".

Сравнение константы слева

Представьте, что у вас есть enum, который отвечает за статус пользователя в системе: "онлайн", "офлайн" и "занят". public enum UserStatus { ONLINE, OFFLINE, BUSY } public class User { ... @Column(name = "status") @Enumerated(EnumType.STRING) private UserStatus status; ... } Скорее всего для выполнения бизнес-логики вам потребуется проверять статус пользователя. if (user.getStatus().equals(UserStatus.

Представьте, что у вас есть enum, который отвечает за статус пользователя в системе: "онлайн", "офлайн" и "занят".

public enum UserStatus {

    ONLINE, OFFLINE, BUSY
    
}
public class User {

    ...

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private UserStatus status;
    
    ...

}

Скорее всего для выполнения бизнес-логики вам потребуется проверять статус пользователя.

if (user.getStatus().equals(UserStatus.ONLINE)) {
    // to do something
}

Вроде бы все отлично, миссия выполнена. Но есть одно НО. Что если getStatus() вернет вам null? Правильно, вы получите NullPointerException.

Чтобы этого избежать следует придерживаться правила "Сравнения константы слева". Оно очень простое. В нашем примере, мы точно уверены, что UserStatus.ONLINE существует, поэтому .equals() стоит вызывать от него.

if (UserStatus.ONLINE.equals(user.getStatus())) {
    // to do something
}

В остальных подобных ситуациях делайте также, например со строками:

if ("Иванов".equals(user.getLastName())) {
    // to do something
}

Это простое правило защитит вас от NullPointerException.