5

Лучший способ "отрицать" оператор instanceof

11

Проблема: Как красиво отрицать instanceof в Java?

Я задумался, существует ли более красивый способ отрицать instanceof в Java. На данный момент я использую следующий код:

if (!(myObject instanceof SomeClass)) { /* делаем что-то */ }

Однако мне кажется, что должна быть более элегантная синтаксическая конструкция для этого.

Существует ли такой синтаксис, и как он выглядит?


РЕДАКТИРОВАНИЕ:

Под "красивым" я имею в виду что-то вроде этого:

if (myObject !instanceof SomeClass) { /* делаем что-то */ } // компиляция не проходит

5 ответ(ов)

4

Нет, лучшего способа нет; ваш вариант является каноническим.

1

Когда вы говорите "красиво", я не знаю, что вы имеете в виду, но как насчет этого? Лично я считаю, что это выглядит хуже, чем классическая форма, которую вы привели, но кому-то может это понравиться...

if (!(str instanceof String)) { /* ... */ }

В этом варианте использование оператора отрицания ! делает условие более читаемым для некоторых людей, но в то же время оно может показаться менее привычным тем, кто предпочитает традиционный стиль. Как бы то ни было, выбор стиля часто зависит от личных предпочтений и принятого в команде подхода к кодированию.

0

Обычно вам не нужно использовать только if, но и добавить else. Например, код

if(!(str instanceof String)) { /* делаем что-то другое */ } 
else { /* делаем что-то еще */ }

можно переписать как

if(str instanceof String) { /* делаем что-то еще */ } 
else { /* делаем что-то другое */ }

Или вы можете написать код так, чтобы не нужно было проверять, является ли это строкой или нет. Например, вот такой код:

if(!(str instanceof String)) { str = str.toString(); } 

можно упростить до

str = str.toString();

В этом случае, если str уже являетесь строкой, то метод toString() просто вернет себя, и все будет работать правильно, независимо от типа str.

0

Вы можете использовать статические импорты, если ваша моральная позиция это допускает. Рассмотрим следующий код:

public class ObjectUtils {
    private final Object obj;

    private ObjectUtils(Object obj) {
        this.obj = obj;
    }

    public static ObjectUtils thisObj(Object obj) {
        return new ObjectUtils(obj);
    }

    public boolean isNotA(Class<?> clazz) {
        return !clazz.isInstance(obj);
    }
}

В этом коде создается класс ObjectUtils, который позволяет проверить, является ли объект экземпляром определенного класса. Мы создаем экземпляр ObjectUtils, используя статический метод thisObj, а затем вызываем метод isNotA для проверки.

Теперь давайте рассмотрим Main класс:

import static notinstanceof.ObjectUtils.*;

public class Main {
    public static void main(String[] args) {
        String a = "";
        if (thisObj(a).isNotA(String.class)) {
            System.out.println("It is not a String");
        }
        if (thisObj(a).isNotA(Integer.class)) {
            System.out.println("It is not an Integer");
        }
    }    
}

В этом примере мы используем статический импорт, чтобы избежать явного указания класса ObjectUtils. Если строка a не является строкой, то будет напечатано "It is not a String", и аналогично для Integer.

Однако стоит отметить, что хотя такой подход может быть интересным с точки зрения использования "флуентного" интерфейса, на практике я бы не рекомендовал его использовать. Это может запутать читателей вашего кода, так как привычный стиль является более понятным и предсказуемым. Поэтому, если вам не нужны особые преимущества этого подхода, лучше придерживаться классических методов.

0

Если вам так удобнее, вы можете сделать что-то вроде этого, используя Java 8:

public static final Predicate<Object> isInstanceOfTheClass = 
    objectToTest -> objectToTest instanceof TheClass;

public static final Predicate<Object> isNotInstanceOfTheClass = 
    isInstanceOfTheClass.negate(); // либо objectToTest -> !(objectToTest instanceof TheClass)

if (isNotInstanceOfTheClass.test(myObject)) {
    // выполнить что-то
}

Таким образом, вы можете легко проверять, является ли объект экземпляром указанного класса, и использовать отрицательную проверку для выполнения действий в других случаях.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь