【发布时间】:2011-02-08 17:55:31
【问题描述】:
通过使用java反射,我们可以很容易地知道一个对象是否是一个数组。判断一个对象是否为集合(Set、List、Map、Vector...)的最简单方法是什么?
【问题讨论】:
标签: java
通过使用java反射,我们可以很容易地知道一个对象是否是一个数组。判断一个对象是否为集合(Set、List、Map、Vector...)的最简单方法是什么?
【问题讨论】:
标签: java
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());
【讨论】:
myArray 引用为空,您将获得 NPE。因此需要检查 null 作为结果。通过instanceof 进行检查是没有必要的。见stackoverflow.com/questions/2950319/…
else 子句或检查null。至少有了这个答案,你不得不考虑 null 选项。
obj instanceof Collection。我从来没有得到过NPE。我不需要检查空值。如果obj 为空,此语句的结果将为假。通过反射,您无需明确检查即可获得 NPE。
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
}
这里应该提到一件事:在这些类型的结构中检查正确的顺序很重要。你会发现,如果你在上面的 sn-p 中交换了检查的顺序,代码仍然可以编译,但是将不再工作。那就是下面的代码不起作用:
// 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
}
问题是List<?>是-aCollection<?>,所以它会通过第一个测试,而else意味着它永远不会达到第二个测试。 你必须从最具体到最一般的类型进行测试。
【讨论】:
List。重点仍然存在。
测试对象是否实现java.util.Collection 或java.util.Map。 (Map 必须单独测试,因为它不是Collection 的子接口。)
【讨论】:
您是否考虑过使用 @987654321@ ?
比如,说
if(myObject instanceof Collection) {
Collection myCollection = (Collection) myObject;
虽然不是那种纯粹的 OOP 风格,但它主要用于所谓的“类型升级”。
【讨论】:
Collection 和 Collection<?> 是等价的,因为它们都将包含 Object 实例。因此,泛型在这里没有附加价值。