Почему переменная "Class" не может быть передана instanceof? - PullRequest
76 голосов
/ 07 апреля 2010

Почему этот код не компилируется?

    public boolean isOf(Class clazz, Object obj){
        if(obj instanceof clazz){
            return true;
        }else{
            return false;
        }
    }

Почему я не могу передать переменную класса instanceof?

Ответы [ 4 ]

120 голосов
/ 07 апреля 2010

Оператор instanceof работает с ссылочными типами, такими как Integer, а не с объектами, такими как new Integer(213).Вы, вероятно, захотите что-то вроде

clazz.isInstance(obj)

Примечание: ваш код будет более лаконичным, если вы напишите

public boolean isOf(Class clazz, Object obj){
    return clazz.isInstance(obj)
}

Хотя вы не совсем уверены, нужен ли вам метод.

12 голосов
/ 07 апреля 2010

instanceof может использоваться только с явными именами классов (указанными во время компиляции).Чтобы выполнить проверку runtime , вы должны выполнить:

clazz.isInstance(obj)

Это имеет небольшое преимущество перед clazz.isAssignableFrom(..), так как оно имеет дело с делом obj == null лучше.

3 голосов
/ 02 июля 2013

Как уже упоминалось, вы не можете передать переменную класса в instanceof, потому что переменная класса ссылается на экземпляр Object , тогда как правая рука instanceof должна быть тип .То есть instanceof не означает «y является экземпляром объекта x», это означает «y является экземпляром типа X».В случае, если вы не знаете разницу между объектом и типом, рассмотрите:

Object o = new Object();

Здесь типом является Object, а o является ссылкой наэкземпляр объекта с этим типом.Таким образом:

if(o instanceof Object)

допустимо, но

if(o instanceof o)

не потому, что o справа является объектом,не тип.

Более конкретно для вашего случая, экземпляр класса не является типом, это Object (который создается для вас JVM).В вашем методе Class - это тип, но clazz - это объект (ну, ссылка на объект)

Вам нужен способ сравнения объекта с объектом класса.Оказывается, это популярно, поэтому вам предоставляется метод класса Object: isInstance().

Вот документ Java для isInstance, который объясняет это лучше:

public boolean isInstance(Object obj)

Определяет, является ли указанный объект совместимым с назначением с представленным объектомэтим классом.Этот метод является динамическим эквивалентом оператора instanceof языка Java.Метод возвращает значение true, если указанный аргумент Object не равен NULL и может быть приведен к ссылочному типу, представленному этим объектом Class, без вызова ClassCastException.В противном случае он возвращает false.

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

Параметры: obj - проверяемый объект
Возвращает: true, если obj являетсяЭкземпляр этого класса
С: JDK1.1

3 голосов
/ 07 апреля 2010

Во-первых, instanceof требует, чтобы операнд справа был фактическим классом (например, obj instanceof Object или obj instanceof Integer), а не переменной типа Class.Во-вторых, вы совершили довольно распространенную ошибку новичка, которую вам на самом деле не следует делать ... по следующей схеме:

if ( <i>conditional_expression</i> ){
    return true;
} else{
    return false;
}

Вышеприведенное может быть преобразовано в:

return <i>conditional_expression</i>;

Вы должнывсегда выполняйте этот рефакторинг, так как он устраняет избыточный оператор if ... else.Аналогично, выражение return <i>conditional_expression</i> ? true : false; рефакторируемо для того же результата.

...