1

我有一个应用程序,它使用生成各种类型的对象和数据结构的代码,将它们作为 Object 实例返回,并且想要一种通用的方法来确定这些对象中的任何一个是否为“空”(或 null)。

(这不是设计问题,也不是是否应该使用这种方法的问题,而是针对现有需求优化解决方案的问题。)

所以,这是一个简单的开始:

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?

4

2 回答 2

6

Instead of the ugly instanceofs, split up the method into several methods with the same name but different args. e.g.

static boolean isEmpty(Object[] array)
static boolean isEmpty(Collection collection)
static boolean isEmpty(CharSequence cs)

Instead of reflection, if you really want your own interface for special objects, declare that interface, and then, for consistency with the above, offer the static utility

static boolean isEmpty(IMayBeEmpty imbe);
于 2012-06-11T23:47:32.203 回答
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) 永远不会匹配任何内容,因为您无法构造该类型的任何内容。

于 2012-06-12T04:32:07.333 回答