Почему переменная" Class " не может быть передана в instanceof?


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

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

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

4 74

4 ответа:

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

clazz.isInstance(obj)

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

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

не совсем уверен ,что вам нужен метод больше, хотя.

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

clazz.isInstance(obj)

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

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

if ( conditional_expression ){
    return true;
} else{
    return false;
}

вышесказанное может быть преобразовано в:

return conditional_expression;

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

как уже упоминалось, вы не можете передать переменную класса в instanceof потому что переменная класса ссылается на экземпляр объект, в то время как правая рука instanceof должен быть тип. То есть, instanceof не означает "y является экземпляром объекта x", это означает"y является экземпляром типа X". Если вы не знаете разницы между объектом и типом, подумайте:

Object o = new Object();

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

if(o instanceof Object)

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

if(o instanceof o)

не так o С правой стороны-это объект, а не тип.

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

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

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

public boolean isInstance(Object obj)

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

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

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