如何检查对象是不是是Java中的集合类型?
Posted
技术标签:
【中文标题】如何检查对象是不是是Java中的集合类型?【英文标题】:How to check if an Object is a Collection Type in Java?如何检查对象是否是Java中的集合类型? 【发布时间】:2011-02-08 17:55:31 【问题描述】:通过使用java反射,我们可以很容易地知道一个对象是否是一个数组。判断一个对象是否为集合(Set、List、Map、Vector...)的最简单方法是什么?
【问题讨论】:
【参考方案1】:if (x instanceof Collection<?>)
if (x instanceof Map<?,?>)
【讨论】:
请注意其中的?
。您无法访问已擦除的组件类型。如果您需要知道集合中可能包含哪些类型的对象,则需要查看元素本身。
在没有元素的情况下,如何找出集合中有哪些对象?【参考方案2】:
更新:这里有两种可能的情况:
您正在确定一个对象是否是一个集合;
您正在确定一个类是否是一个集合。
解决方案略有不同,但原理相同。您还需要定义究竟是什么构成了“集合”。实现 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());
我认为这两种方法的效率不会有很大的不同。
【讨论】:
因为这个任务可以在没有“instanceof”的情况下解决 @den bardmadym 为什么你不想使用 instaceof? 我相信 instanceof 比 isAssignableFrom 更高效,不是吗? 我只会在必要时使用反射(isAssignableFrom),即在编译时不知道要测试的类。否则,一个简单的 instanceof 更容易输入和阅读,恕我直言。 @duduamar 可能你是对的(应该看看字节码)。肯定 isAssignableFrom 的使用不能胜过 instanceof【参考方案3】:既然你在问题中提到了反思;
boolean isArray = myArray.getClass().isArray();
boolean isCollection = Collection.class.isAssignableFrom(myList.getClass());
boolean isMap = Map.class.isAssignableFrom(myMap.getClass());
【讨论】:
最佳答案在这里 IMO 您也可以使用它,如果myArray
引用为空,您将获得 NPE。因此需要检查 null 作为结果。通过instanceof
进行检查是没有必要的。见***.com/questions/2950319/…
@Alexandr:其他答案都没有else
子句或检查null
。至少有了这个答案,你不得不考虑 null 选项。
@Foumpie,obj instanceof Collection
。我从来没有得到过NPE。我不需要检查空值。如果obj
为空,此语句的结果将为假。通过反射,您无需明确检查即可获得 NPE。【参考方案4】:
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
意味着它永远不会达到第二个测试。 你必须从最具体到最一般的类型进行测试。
【讨论】:
地图不扩展集合。 @Thilo:脑残;修改为List
。重点仍然存在。【参考方案5】:
测试对象是否实现java.util.Collection
或java.util.Map
。 (Map
必须单独测试,因为它不是Collection
的子接口。)
【讨论】:
【参考方案6】:您是否考虑过使用 @987654321@
?
比如,说
if(myObject instanceof Collection)
Collection myCollection = (Collection) myObject;
虽然不是那种纯粹的 OOP 风格,但它主要用于所谓的“类型升级”。
【讨论】:
像我这样的老开发人员有时倾向于依赖 java1.5 之前的符号来处理像这样的不可编译示例,尤其是当泛型符号没有增加任何价值时。 增加的价值是您明确声明类型未知。无法以 1.5 之前的符号表示此信息。 @Max 表现得像个复活者?我知道你在搜索什么点 ;-) 无论如何,在 Java 5+ 中,Collection
和 Collection<?>
是等价的,因为它们都将包含 Object
实例。因此,泛型在这里没有附加价值。以上是关于如何检查对象是不是是Java中的集合类型?的主要内容,如果未能解决你的问题,请参考以下文章