Как определить класс объекта? - PullRequest
474 голосов
/ 12 февраля 2009

Если класс B и класс C расширяют класс A, и у меня есть объект типа B или C, как я могу определить, к какому типу это экземпляр?

Ответы [ 7 ]

747 голосов
/ 12 февраля 2009
if (obj instanceof C) {
//your code
}
318 голосов
/ 12 февраля 2009

Использовать Object.getClass () . Возвращает тип времени выполнения объекта.

154 голосов
/ 21 августа 2014

Были представлены несколько правильных ответов, но есть еще несколько методов: Class.isAssignableFrom() и просто попытка сотворить объект (который может выдать ClassCastException).

Возможные способы суммированы

Давайте подведем итоги возможных способов проверить, является ли объект obj экземпляром типа C:

// Method #1
if (obj instanceof C)
    ;

// Method #2
if (C.class.isInstance(obj))
    ;

// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
    ;

// Method #4
try {
    C c = (C) obj;
    // No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}

// Method #5
try {
    C c = C.class.cast(obj);
    // No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}

Различия в null обработке

Существует разница в обработке null:

  • В первых двух методах выражения оцениваются как false, если obj равно null (null не является экземпляром чего-либо).
  • Третий метод, очевидно, выдаст NullPointerException.
  • 4-й и 5-й методы наоборот принимают null, потому что null может быть приведен к любому типу!

Запомните: null не является экземпляром любого типа, но может быть приведен к любому типу.

Примечания

  • Class.getName() не должен использоваться для выполнения "is-instance-of" теста, поскольку объект не относится к типу C, но является его подклассом, он может иметь совершенно другой имя и пакет (поэтому имена классов, очевидно, не будут совпадать), но он по-прежнему имеет тип C.
  • По той же причине наследования Class.isAssignableFrom() не является симметричным :
    obj.getClass().isAssignableFrom(C.class) вернет false, если тип obj является подклассом C.
31 голосов
/ 12 февраля 2009

Вы можете использовать:

Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object

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

24 голосов
/ 12 февраля 2009

Любое использование любого из предложенных методов считается запахом кода, основанным на плохом дизайне ОО.

Если у вас хороший дизайн, вам не нужно использовать getClass() или instanceof.

Подойдет любой из предложенных методов, но нужно помнить только о дизайне.

15 голосов
/ 13 мая 2014

Мы можем использовать отражение в этом случае

objectName.getClass().getName();

Пример: - * +1004 *

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String name = request.getClass().getName();
}

В этом случае вы получите имя класса, объект которого передается в HttpServletRequest переменную интерфейса.

13 голосов
/ 12 февраля 2009

В классе "Class" также есть метод .isInstance. если вы получаете класс объекта через myBanana.getClass(), вы можете увидеть, является ли ваш объект myApple экземпляром того же класса, что и myBanana через

myBanana.getClass().isInstance(myApple)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...