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であるかどうかを確認することもできます(実際には、リフレクションが多すぎる可能性がありますが、ここに含めます完全を期すために。)

isEmpty()を持つCollectionと同様に、上記の場合に含めるために、isEmpty()メソッドの代わりにlength()またはsize()メソッドを持つ非常に一般的に使用されるトップレベルクラスはありますか?

4

2 に答える 2

6

醜いinstanceofsの代わりに、メソッドを同じ名前で引数が異なるいくつかのメソッドに分割します。例えば

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

リフレクションの代わりに、特別なオブジェクト用の独自のインターフェイスが本当に必要な場合は、そのインターフェイスを宣言してから、上記との一貫性を保つために、静的ユーティリティを提供します

static boolean isEmpty(IMayBeEmpty imbe);
于 2012-06-11T23:47:32.203 に答える
1

このメソッドは、少なくとも一般的なisEmpty(Object)問題の問題を解決します。ただし、これではコンパイル時の安全性が得られず、要求された正確な型に対して存在するメソッドなしで呼び出すと、ランタイムエラーが発生します。「MethodUtils」クラスはapachecommons-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 に答える