Нужна ли нулевая проверка перед вызовом instanceof?

1187

Будет ли null instanceof SomeClass возвращать false или выбросить NullPointerException?

  • 0
    Он также «важен» или, по крайней мере, очень полезен как начальная (или очень ранняя) строка «наилучшей практики» для любого метода сравнения или равенства или аналогичного метода, который предназначен для успешной работы только с ненулевыми объектами того же типа, и защищает вас от «глупых дел» в одну строку. меньше кода = меньше ошибок.
  • 13
    Чтобы взвесить "это полезно?" дискуссия - я никогда не писал свой собственный Java-код (поэтому не всегда легко знать, где спецификации, и компиляция теста будет очень нетривиальной), но в настоящее время я вручную конвертирую Java в JavaScript. Мой код не выполнялся по нулевой ссылке, и поиск в Google позволил мне увидеть принятый ответ, который подтвердил, что это было ожидаемое поведение и что я пропускал неявную нулевую проверку. Очень полезно, в моем случае.
Теги:
nullpointerexception
null

7 ответов

1520
Лучший ответ

Нет, нулевая проверка не требуется перед использованием instanceof.

Выражение x instanceof SomeClass имеет значение false если x равно null.

Из спецификации языка Java, раздел 15.20.2, "Оператор сравнения типов instanceof":

"Во время выполнения результат оператора instanceof равен true если значение RelationalExpression не равно null и ссылка может быть приведена к ReferenceType без повышения ClassCastException. В противном случае результат равен false ".

Так что, если операнд нулевой, результат ложный.

  • 343
    Этот ответ является более правильным, чем try it потому что текущее поведение отличается от гарантированного поведения .
  • 3
    Этот вопрос вступает в игру во время главы Джошуа Блоха о равенстве объектов в Effective Java - amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683
Показать ещё 6 комментариев
254

Использование нулевой ссылки в качестве первого операнда для instanceof возвращает false.

  • 256
    (И теперь это занимает 10 секунд, чтобы найти этот вопрос в Google)
  • 10
    Слишком коротко. Хороший ответ дает контекст и объяснение.
63

Очень хороший вопрос. Я просто пробовал для себя.

public class IsInstanceOfTest {

    public static void main(final String[] args) {

        String s;

        s = "";

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));

        s = null;

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));
    }
}

Печать

true
true
false
false

JLS/15.20.2. Тип сравнения Оператор instanceof

Во время выполнения результат оператора instanceof равен true, если значение RelationalExpression не равно null, и ссылка может быть передана в ReferenceType без повышения ClassCastException. В противном случае результат false.

API/Class # isInstance (Object)

Если этот объект Class представляет интерфейс, этот метод возвращает true, если класс или любой суперкласс указанного аргумента Object реализует этот интерфейс; он возвращает false в противном случае. Если этот объект Class представляет примитивный тип, этот метод возвращает false.

  • 0
    Вроде путаницы. s является строкой, потому что она говорит "String s", s не является строкой, потому что это нуль. Так что, черт возьми, с?
  • 1
    @KaiWang s это просто переменная ссылки на объект. Он может ссылаться на реально существующий объект ( "" ) или может ссылаться на ( null ) буквальную ссылку.
Показать ещё 3 комментария
24

Нет, нет. instanceof вернет false, если его первый операнд null.

6

Просто как лакомый кусочек:

Even ( ((A)null) instanceof A) вернет false.


(Если приведение типов к null кажется неожиданным, иногда вам приходится это делать, например, в таких ситуациях:

public class Test
{
  public static void test(A a)
  {
    System.out.println("a instanceof A: " + (a instanceof A));
  }

  public static void test(B b) {
    // Overloaded version. Would cause reference ambiguity (compile error)
    // if Test.test(null) was called without casting.
    // So you need to call Test.test((A)null) or Test.test((B)null).
  }
}

Поэтому Test.test((A)null) выведет a instanceof A: false.)


PS: Если вы нанимаете, пожалуйста, не используйте это как вопрос собеседования. : D

6

Нет Java буквальный null не является экземпляром какого-либо класса. Поэтому он не может быть экземпляром какого-либо класса. instanceof вернет либо false либо true поэтому <referenceVariable> instanceof <SomeClass> возвращает false если значение referenceVariable равно нулю.

  • 4
    Это объяснение звучит странно, но я знаю, что вы имеете в виду :-)
  • 0
    @ Крис ты за комментарий Я понял, что ты имеешь в виду :). Отредактировал ответ немного :).
2

Оператор instanceof не нуждается в явных проверках null, так как он не бросает NullPointerException, если операнд null.

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

Если операнд null, оператор instanceof возвращает false и, следовательно, явные проверки null не требуются.

Рассмотрим приведенный ниже пример,

public static void main(String[] args) {
         if(lista != null && lista instanceof ArrayList) {                     //Violation
                System.out.println("In if block");
         }
         else {
                System.out.println("In else block");
         }
}

Правильное использование instanceof показано ниже,

public static void main(String[] args) {
      
         if(lista instanceof ArrayList){                     //Correct way
                  System.out.println("In if block");
         }
            else {
                 System.out.println("In else block");
         }  
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню