Ответ 1
if (x instanceof Collection<?>){
}
if (x instanceof Map<?,?>){
}
Используя java-отражение, мы можем легко узнать, является ли объект массивом. Самый простой способ определить, является ли объект коллекцией (Set, List, Map, Vector...)?
if (x instanceof Collection<?>){
}
if (x instanceof Map<?,?>){
}
Обновление: есть два возможных сценария:
Вы определяете, является ли объект коллекцией,
Вы определяете, является ли класс коллекцией.
Решения немного отличаются, но принципы одинаковы. Вам также необходимо определить, что именно представляет собой "коллекцию". Реализация Collection
или Map
будет охватывать сборники Java.
Решение 1:
public static boolean isCollection(Object ob) {
return ob instanceof Collection || ob instanceof Map;
}
Решение 2:
public static boolean isClassCollection(Class c) {
return Collection.class.isAssignableFrom(c) || Map.class.isAssignableFrom(c);
}
(1) также может быть реализовано в терминах (2):
public static boolean isCollection(Object ob) {
return ob != null && isClassCollection(ob.getClass());
}
Я не думаю, что эффективность любого метода будет сильно отличаться от эффективности.
Поскольку вы упомянули отражение в своем вопросе,
boolean isArray = myArray.getClass().isArray();
boolean isCollection = Collection.class.isAssignableFrom(myList.getClass());
boolean isMap = Map.class.isAssignableFrom(myMap.getClass());
Java удобно имеет оператор instanceof
(JLS 15.20.2), чтобы проверить, является ли данный объект заданным типом.
if (x instanceof List<?>) {
List<?> list = (List<?>) x;
// do something with list
} else if (x instanceof Collection<?>) {
Collection<?> col = (Collection<?>) x;
// do something with col
}
Здесь следует упомянуть одну вещь: важно в этих конструкциях проверить правильный порядок. Вы обнаружите, что если бы вы поменяли порядок проверки в приведенном выше фрагменте, код все равно будет компилироваться, но он больше не будет работать. То есть следующий код не работает:
// DOESN'T WORK! Wrong order!
if (x instanceof Collection<?>) {
Collection<?> col = (Collection<?>) x;
// do something with col
} else if (x instanceof List<?>) { // this will never be reached!
List<?> list = (List<?>) x;
// do something with list
}
Проблема в том, что a List<?>
is-a Collection<?>
, поэтому он пройдет первый тест, а else
означает, что он никогда не достигнет второго теста. Вам нужно протестировать наиболее специфичный для наиболее общего типа.
Проверьте, реализует ли объект либо java.util.Collection
, либо java.util.Map
. (Map
нужно тестировать отдельно, потому что это не суб-интерфейс Collection
.)
Считаете ли вы, что используете instanceof
?
Например, скажем
if(myObject instanceof Collection) {
Collection myCollection = (Collection) myObject;
Хотя это не тот чистый стиль ООП, он в основном используется для так называемой "эскалации типа".