Два варианта проверки типов во время выполнения с помощью обобщений:
Вариант 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
.