Невозможно выполнить проверку экземпляра с параметризованным типом ArrayList <Foo>
Следующий код:
((tempVar instanceof ArrayList<Foo>) ? tempVar : null);
вызывает:
Невозможно выполнить проверку instanceof
с параметризованным типом ArrayList<Foo>
. Используйте форму ArrayList<?>
, так как дополнительная информация о типе типа будет удалена во время выполнения
Может ли кто-нибудь объяснить мне, что подразумевается под "дополнительной информацией общего типа, будет стерто во время выполнения" и как это исправить?
Ответы
Ответ 1
Это означает, что если у вас есть что-то, что параметризовано, например. List<Foo> fooList = new ArrayList<Foo>();
, информация Generics будет удалена во время выполнения. Вместо этого это увидит JVM List fooList = new ArrayList();
.
Это называется type erasure. JVM не имеет параметризованной информации о типе List
(в примере) во время выполнения.
Исправить? Поскольку JVM не имеет информации о параметризованном типе во время выполнения, вы не можете сделать instanceof
из ArrayList<Foo>
. Вы можете "сохранить" параметризованный тип явно и провести там сравнение.
Ответ 2
Вы всегда можете сделать это вместо
try
{
if(obj instanceof ArrayList<?>)
{
if(((ArrayList<?>)obj).get(0) instanceof MyObject)
{
// do stuff
}
}
}
catch(NullPointerException e)
{
e.printStackTrace();
}
Ответ 3
Из-за стирания типа параметризованный тип ArrayList
не будет известен во время выполнения. Лучшее, что вы можете сделать с instanceof
, - проверить, является ли tempVar
ArrayList
(чего-либо). Чтобы сделать это универсальным способом, используйте:
((tempVar instanceof ArrayList<?>) ? tempVar : null);
Ответ 4
Этого достаточно:
if(obj instanceof ArrayList<?>)
{
if(((ArrayList<?>)obj).get(0) instanceof MyObject)
{
// do stuff
}
}
Фактически, instanceof
проверяет, является ли левый операнд null
или нет, и возвращает false
, если это фактически null
.
Итак: не нужно ловить NullPointerException
.
Ответ 5
Вы не можете это исправить. Информация типа для Generics недоступна во время выполнения, и у вас не будет доступа к ней. Вы можете только проверить содержимое массива.
Ответ 6
Оператор экземпляра работает во время выполнения. Но java не несет информацию параметризованного типа во время выполнения. Они стираются во время компиляции. Отсюда и ошибка.
Ответ 7
Вы всегда можете это сделать
Создать класс
public class ListFoo {
private List<Foo> theList;
public ListFoo(List<Foo> theList {
this.theList = theLista;
}
public List<Foo> getList() {
return theList;
}
}
Не то же самое, но...
myList = new ArrayList<Foo>;
.....
Object tempVar = new ListFoo(myList);
....
((tempVar instanceof ListFoo) ? tempVar.getList() : null);
Ответ 8
Вы можете использовать
boolean isInstanceArrayList = tempVar.getClass() == ArrayList.class