我有一个应用程序,它使用生成各种类型的对象和数据结构的代码,将它们作为Object实例返回,并且想要一种通用的方法来确定这些对象中是否有任何“空”(或为空)。
(这不是设计问题,也不是应该使用这种方法的问题,而是优化现有要求的解决方案的问题。)
所以,这是一个简单的去:
public static boolean isEmpty(Object content)
{
if (content == null)
{
return true;
}
else if (content instanceof CharSequence)
{
return (((CharSequence)content).length() == 0);
}
else if (content instanceof Collection<?>)
{
return ((Collection<?>)content).isEmpty();
}
else if (content instanceof Object[])
{
return (((Object[])content).length == 0);
}
else // Use reflection (an exaggeration, for demo purposes)
{
try
{
Method isEmpty = content.getClass().
getDeclaredMethod("isEmpty", (Class<?>[])null);
if (isEmpty != null)
{
Object result = isEmpty.invoke(content, (Object[])null);
if (result instanceof Boolean)
{
return (Boolean)result;
}
}
}
catch (Exception e)
{
}
}
return false;
}
在绩效或覆盖面方面有任何潜在改进的想法吗?
例如,反射也可用于确定对象是否具有length()或size()方法,调用它并查看结果是否为0.(实际上,反射可能太多,但我是包括它在这里完整。)
是否有一个非常常用的顶级类,它有一个length()或size()方法,而不是isEmpty()方法,包含在上面的情况中,类似于具有isEmpty()的Collection?
答案 0 :(得分:5)
而不是丑陋的instanceofs,将方法拆分为几个具有相同名称但不同args的方法。 e.g。
static boolean isEmpty(Object[] array)
static boolean isEmpty(Collection collection)
static boolean isEmpty(CharSequence cs)
如果您真的想要特殊对象的自己的接口,而不是反射,请声明该接口,然后,为了与上面的一致,提供静态实用程序
static boolean isEmpty(IMayBeEmpty imbe);
答案 1 :(得分:1)
这种方法至少可以解决你的泛型isEmpty(Object)问题。但是,您没有使用此编译时安全性,并且在没有针对所请求的确切类型的现有方法的情况下调用它将产生运行时错误。注意“MethodUtils”类来自apache commons-beanutils,虽然你可以直接使用反射,但为了简单起见,我在这里使用beanutils。
“invokeExactcMethod”方法在给定类中查找具有给定名称的静态方法,该名称具有要传递的对象数组的兼容参数。因此,如果对象的运行时类型是ArrayList,它将查找isEmpty(ArrayList),然后查找isEmpty(AbstractList),然后查找isEmpty(List)。然后,如果它可以找到它,则调用该方法,否则抛出NoSuchMethodException。
public class MyUtility {
static boolean isEmpty(Object object) {
if (object == null) {
return true;
}
else {
try {
return MethodUtils.invokeStaticMethod(
MyUtility.class, "isEmpty", new Object[]{object});
}
catch (NoSuchMethodException e) {
throw new IllegalArgumentException(e);
}
catch (IllegalAccessException e) {
throw new IllegalArgumentException(e);
}
catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
}
“invokeExactStaticMethod”更具确定性,不使用赋值兼容性,但使用精确的签名匹配。这意味着isEmpty(List)永远不会匹配任何东西,因为你不能构造任何类型的东西。