Перевірте, чи об'єкт є екземпляром типу параметра


87

Чи є спосіб визначити, чи є об’єкт екземпляром загального типу?

public <T> test(Object obj) {
    if (obj instanceof T) {
        ...
    }
}

Це явно не працює. Чи є альтернатива? Як я хочу використовувати відображення Java для створення екземпляра класу, а потім перевірити, щоб переконатися, що він має загальний тип T.

Відповіді:


129

Єдиний спосіб зробити цю перевірку - це якщо у вас є Classоб’єкт, що представляє тип:

Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
   //...
}

Якщо ви не хочете отримувати typeяк параметр методу, можливо, ви хочете його ініціалізувати:Class type = ((T) new Object()).getClass();
JordiVilaplana

9
@JordiVilaplana Це неправильно, це дасть вам java.lang.Object як клас. Перевірте це: ideone.com/bxt9Jq
Шрі Харша Чилакапаті

3
Використання:Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Ton Snoei 02

22

Щоб розширити зразок Марка Пітерса, часто ви хочете зробити щось на зразок:

Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
   T t = type.cast(obj);
   // ...
}

11

Якщо ви не хочете передавати тип класу як параметр, як згадав Марк Пітерс, ви можете використовувати наступний код. Слава Девіду О'Меарі.

  Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                  .getActualTypeArguments()[0];
  if (type.isInstance(obj)) {
      ...
  }

5
Це даєType safety: Unchecked cast from Type to Class<T>
Марко Сулла

5

Ви можете спробувати це,

// Cast your object to the generic type.
T data = null;
try {
    data = (T) obj;
} catch (ClassCastException cce) {
    // Log the error.
}

// Check if the cast completed successfully.
if(data != null) {
    // whatever....
}

7
Це не працює! Акторський склад вдався для всіх типів. Ось чому він видає попередження компіляції "Непровірений привід".
Lii 02

3

Доцільніше було б встановити обмеження на те, де тип Tвикористовується для параметризації Classтипу. Коли ви передаєте тип, замість того, щоб використовувати щось на зразок Class<?>, вам слід використовувати Class<? extends T>.


1
Якщо ви хочете знати точний тип T під час виконання, важливо вимагати, щоб абонент передавав клас <T>, а не клас <? поширюється T>. Наприклад, код Puce не компілюється з Class <? поширюється T>.
Теодор Мердок,

1

Це спрацює (частково), лише якщо у вас є об'єкт типу T. Тоді ви можете отримати клас цього об'єкта, побачити java.lang.Class<T>і знайти, чи він такий самий, як і об'єкт, про який йде мова.

Але зауважте, що це суперечить самій причині, по якій ми маємо жанри: використання загального типу - це спосіб сказати, що вам байдуже, який це тип насправді (до верхньої та нижньої меж, які можуть бути вказані).


Клас <?>, Повернутий із виклику .getClass () на ненульовому екземплярі T, не гарантовано є класом <T>. Найкраще, що ви можете гарантувати, це те, що це Клас <? поширюється T>.
Теодор Мердок,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.