Два варіанти перевірки типу виконання за допомогою дженериків:
Варіант 1 - Пошкодити ваш конструктор
Припустимо, ви переосмислюєте indexOf (...), і ви хочете перевірити тип лише на продуктивність, щоб зберегти собі ітерацію всієї колекції.
Зробіть брудний конструктор так:
public MyCollection<T>(Class<T> t) {
this.t = t;
}
Тоді ви можете використовувати isAssignableFrom для перевірки типу.
public int indexOf(Object o) {
if (
o != null &&
!t.isAssignableFrom(o.getClass())
) return -1;
//...
Кожен раз, коли ви створюєте об'єкт, вам доведеться повторити:
new MyCollection<Apples>(Apples.class);
Ви можете вирішити, що це не варто. При реалізації ArrayList.indexOf (...) вони не перевіряють, чи відповідає тип.
Варіант 2 - Нехай це не вдасться
Якщо вам потрібно використовувати абстрактний метод, який вимагає вашого невідомого типу, тоді все, що ви дійсно хочете, - це компілятор перестав плакати про instanceof . Якщо у вас є такий метод:
protected abstract void abstractMethod(T element);
Ви можете використовувати його так:
public int indexOf(Object o) {
try {
abstractMethod((T) o);
} catch (ClassCastException e) {
//...
Ви кидаєте об'єкт на T (ваш загальний тип), просто щоб обдурити компілятор. Ваш актер нічого не робить під час виконання , але ви все одно отримаєте ClassCastException, коли спробуєте передати неправильний тип об'єкта у свій абстрактний метод.
ПРИМІТКА 1. Якщо ви робите додаткові неперевірені касти в абстрактному методі, ваші ClassCastExceptions потраплять сюди. Це може бути добре чи погано, тому продумайте.
ПРИМІТКА 2: Ви отримуєте безкоштовну нульову перевірку, коли використовуєте instanceof . Оскільки ви не можете використовувати його, можливо, вам доведеться перевірити наявність нуля голими руками.
Class.isAssignableFrom
.