Прежде, чем я просматриваю свою общую структуру данных для индекса значения, я хотел бы видеть, параметризован ли он даже экземпляру типа this
.
Но Затмение жалуется, когда я делаю это:
@Override
public int indexOf(Object arg0) {
if (!(arg0 instanceof E)) {
return -1;
}
Это сообщение об ошибке:
Невозможно выполнить проверку экземпляра для параметра типа E. Вместо этого используйте его объект стирания, поскольку информация общего типа будет удалена во время выполнения
Какой лучший способ сделать это?
java
generics
instanceof
typechecking
Ник Хейнер
источник
источник
Class.isAssignableFrom
.Два варианта проверки типов во время выполнения с помощью обобщений:
Вариант 1 - Повредить ваш конструктор
Предположим, вы переопределяете indexOf (...) и хотите проверить тип только на предмет производительности, чтобы сэкономить итерирование всей коллекции.
Сделайте грязный конструктор так:
Затем вы можете использовать isAssignableFrom для проверки типа.
Каждый раз, когда вы создаете экземпляр своего объекта, вам придется повторяться:
Вы можете решить, что это того не стоит. В реализации ArrayList.indexOf (...) они не проверяют соответствие типа.
Вариант 2 - Пусть это не удастся
Если вам нужно использовать абстрактный метод, который требует вашего неизвестного типа, тогда все, что вам действительно нужно, это чтобы компилятор прекратил плакать об instanceof . Если у вас есть такой метод:
Вы можете использовать это так:
Вы приводите объект к T (ваш универсальный тип), просто чтобы обмануть компилятор. Ваше приведение ничего не делает во время выполнения , но вы все равно получите ClassCastException, когда попытаетесь передать объект неправильного типа в ваш абстрактный метод.
ПРИМЕЧАНИЕ 1. Если вы выполняете дополнительные неконтролируемые приведения в вашем абстрактном методе, ваши ClassCastExceptions будут обнаружены здесь. Это может быть хорошо или плохо, так что подумайте.
ПРИМЕЧАНИЕ 2: Вы получаете бесплатную нулевую проверку при использовании instanceof . Так как вы не можете использовать его, вам может потребоваться проверить на ноль голыми руками.
источник
Старый пост, но простой способ сделать общую проверку экземпляра.
источник
При условии, что ваш класс расширяет класс универсальным параметром, вы также можете получить его во время выполнения с помощью отражения, а затем использовать его для сравнения, т.е.
В приведенном выше случае во время выполнения вы получите String.class из getParameterizedClass (), и он будет кэшироваться, поэтому вы не получите никаких дополнительных затрат на отражение при многократных проверках. Обратите внимание, что другие параметризованные типы можно получить по индексу из метода ParameterizedType.getActualTypeArguments ().
источник
У меня была та же проблема, и вот мое решение (очень скромное, @george: на этот раз компиляция И работа ...).
Мой тест был внутри абстрактного класса, который реализует Observer. Обновление метода Observable запускает (...) классом Object, который может быть любым типом Object.
Я только хочу обработать объекты типа T
Решение состоит в том, чтобы передать класс конструктору, чтобы иметь возможность сравнивать типы во время выполнения.
Для реализации нам просто нужно передать класс в конструктор
источник
Или вы можете поймать неудачную попытку бросить в E, например.
источник
С технической точки зрения вам не нужно этого делать, в этом суть универсальности, поэтому вы можете выполнить проверку типа компиляции:
но тогда @Override может быть проблемой, если у вас есть иерархия классов. В противном случае смотрите ответ Ишая.
источник
Тип объекта во время выполнения - относительно произвольное условие для фильтрации. Я предлагаю держать такую грязь подальше от вашей коллекции. Это просто достигается тем, что ваш делегат коллекции передается в конструкцию фильтра.
источник
Comparator
или похожий.)