リフレクションを使用せずにオブジェクトが配列であるかどうかを確認するにはどうすればよいですか?


98

リフレクションを使用せずにオブジェクトが配列である場合、Javaでどのように表示できますか?また、リフレクションを使用せずにすべてのアイテムを反復処理するにはどうすればよいですか?

私はGoogle GWTを使用しているので、リフレクションの使用は許可されていません:(

リフレクションを使用せずに次のメソッドを実装したいと思います。

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

ところで、JavaScriptを使用したくないので、GWT以外の環境でJavaScriptを使用できます。

回答:


247

使用できます Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

これは、オブジェクト型配列とプリミティブ型配列の両方で機能します。

toStringについては、をご覧くださいArrays.toString。配列の型を確認し、適切なtoStringメソッドを呼び出す必要があります。


1
を使用して配列型を見つけることができることを追加する価値がありますobj.getClass().getComponentType()
スティーブチェンバーズ

68

使用できますinstanceof

JLS 15.20.2タイプ比較演算子 instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

実行時に、RelationalExpressionの値instanceoftrueそうではなく、参照をを発生させずにReferenceTypeにキャストできる場合、演算子の結果は次のとおりです。それ以外の場合の結果はです。nullClassCastExceptionfalse

つまり、次のようなことができます。

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

あなたは、オブジェクトがあるかどうかを確認する必要があるだろうinstanceof boolean[]byte[]short[]char[]int[]long[]float[]double[]、またはObject[]、あなたはすべての配列型を検出したい場合。

また、int[][]instanceof Object[]なので、ネストされた配列の処理方法によっては、複雑になる場合があります。

以下のためにtoStringjava.util.Arrays持っているtoString(int[])あなたが使用することができますし、他のオーバーロードを。deepToString(Object[])ネストされた配列にも使用できます。

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

これjava.util.Arraysは非常に反復的です(ただし、非常に反復的です)が、配列を使用したJavaの場合と同じです

こちらもご覧ください


おかげで、それがそれほど単純であることに気づきませんでした。T [] :(
edbrasを

2
ところで、私はまた、何かが配列Class.isArray()(Arrays.deepToString()で使用される)であるかどうかを発見する別の良い方法に気づきました。
edbras 2010

@edbras:はい、それがSteve Kuoが下で言っていたことです。私のソリューションでは、API呼び出しの代わりに純粋な言語構成を使用しています。
polygenelubricants 2010

それは正常に動作します。私はinstanceofを使用していませんが、比較としてgetClassを使用しています。次のようなもの:if(array.getClass == int []。class){Arrays.toString((int [])array); }おかげで、すべての...
edbras

@edbras:java.util.Arraysそうです、そうです。私がリンクしたコードを読んでいるようですね。
polygenelubricants 2010

35

次のコードを使用して、配列の各要素に個別にアクセスできます。

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

これはどの配列でも機能するため、基本となる配列の種類を知る必要がないことに注意してください。


2
isArray()この質問の4年前に投稿された回答では、すでに十分にカバーされていました。
Jason C

15
この答えは素晴らしいです。コンテンツのタイプを知らなくても、配列のサイズを取得して要素を取得する方法を示しているからです。ほとんどの人がこれまでこのようなコードを書いたことはないと思います。
Christopher Yang

@MaartenBodewes- このリンクを使用して、GWTの「リフレクションを使用しない」の意味を決定します。
スティーブンC

10

プリミティブ型の配列間、またはプリミティブ型の配列と参照型の配列の間には、サブタイプの関係はありません。JLS 4.10.3を参照してください。

したがって、次の例はobjが任意の種類の配列であるかどうかを確認するテストとしては正しくありません

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

具体的には、objプリミティブの1次元配列の場合は機能しません。(ただし、すべての配列型はのサブタイプであるため、より高い次元のプリミティブ配列では機能しますObject。ただし、この場合は、これは意味がありません。)

私はGoogle GWTを使用しているので、リフレクションの使用は許可されていません:(

isArray質問の配列部分に対する)最良の解決策は、「リフレクションの使用」と見なされるものによって異なります。

  • GWTでは、呼び出しobj.getClass().isArray()はリフレクション1を使用するものとしてカウントされないため、これが最良のソリューションです。

  • それ以外の場合、オブジェクトに配列型があるかどうかを判断する最良の方法は、一連のinstanceof式を使用することです。

    public boolean isArray(final Object obj) {
        return obj instanceof Object[] || obj instanceof boolean[] ||
           obj instanceof byte[] || obj instanceof short[] ||
           obj instanceof char[] || obj instanceof int[] ||
           obj instanceof long[] || obj instanceof float[] ||
           obj instanceof double[];
    }
  • 次のように、オブジェクトのクラスの名前をいじってみることもできますが、への呼び出しobj.getClass()はリフレクションに隣接しています。

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }

1-より正確にはClass.isArrayこのページのメソッドはGWTでサポートされていると記載されています


0

ユーティリティクラスを作成して、クラスがCollectionMap、またはArrayを表すかどうかを確認できます

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.