У меня есть метод с объектом Stream в качестве аргумента, в этом методе мне нужно выполнить некоторые действия на основе типа Stream. Но instanceof не работает и выдает ошибку компиляции
public <T>boolean objectIsNullOREmpty(Stream<T> str) {
if (str instanceof Stream<String>) {
//do some actions
}
if (Str instanceof Stream<SomeClass>) {
//do some actions
}
}
Ошибка компиляции
Cannot perform instanceof check against parameterized type Stream. Use the form Stream instead since further generic type information will be erased at runtime




Это не проблема потоков. Ошибка отражает способ реализации универсальных типов в Java.
Универсальные типы Java - неподдающийся восстановлению.
В Java универсальные типы имеют меньше информации о типе, доступной во время выполнения, чем во время компиляции. Это так, потому что универсальные шаблоны реализованы в Java с помощью стирание. Большая часть информации об универсальном типе существует только во время компиляции и стирается во время выполнения.
По этой причине невозможно получить объект Class для любого невосстановимого типа. Информация о типе недоступна во время выполнения.
Вы не только не можете получить объект Class для Stream<String>, но и не можете получить объект Class для любого из T, List<T> или List<String>. Все это невоспроизводимые типы.
Оператор instanceof будет работать только с типами, из которых можно получить объект Class. Это тоже хорошо, потому что List<T>, List<String> и List<Integer> используют один и тот же объект класса во время выполнения. Было бы запутанно и подвержено ошибкам, если бы следующий фрагмент оценивался как true:
List<String> strings = new ArrayList<>();
boolean b = strings instanceof List<Integer>;
System.out.println(b);
Вместо этого компилятор Java не позволяет использовать оператор instanceof для неподдающихся повторению типов.
Для объяснения я использую следующий пример: assert new ArrayList<Boolean>().getClass().equals(new ArrayList<String>().getClass())
Чтобы добавить к ответу @scottb, если вам действительно нужна эта структура, вам понадобятся отдельные методы. Вы не можете перегрузить методы из-за стирания, поэтому вы должны назвать каждый метод таким образом, чтобы его сигнатуры были уникальными:
public boolean stringIsNullOREmpty(Stream<String> str) {
//do some actions
}
public boolean someClassIsNullOREmpty(Stream<SomeClass> str) {
//do some actions
}
Вы забыли сказать, что мы можем поместить объект
StringвList<Integer>:-)