web-dev-qa-db-ja.com

Java配列リフレクション:isArrayとinstanceof

以下を使用することで好みや動作に違いはありますか?

if(obj.getClass().isArray()) {}

そして

if(obj instanceof Object[]) {}

171
David Citron

ほとんどの場合、instanceof演算子を使用して、オブジェクトが配列かどうかをテストする必要があります。

一般に、コンパイル時に既知の特定の型にダウンキャストする前に、オブジェクトの型をテストします。たとえば、おそらくInteger[]またはint[]で動作するコードを作成しました。キャストをinstanceofでガードしたい場合:

if (obj instanceof Integer[]) {
    Integer[] array = (Integer[]) obj;
    /* Use the boxed array */
} else if (obj instanceof int[]) {
    int[] array = (int[]) obj;
    /* Use the primitive array */
} else ...

JVMレベルでは、instanceof演算子は特定の "instanceof" バイトコードに変換され、ほとんどのJVM実装で最適化されます。

まれに、リフレクションを使用して、不明なタイプのオブジェクトグラフを走査する場合があります。このような場合、コンパイル時にコンポーネントのタイプがわからないため、isArray()メソッドが役立ちます。たとえば、何らかのシリアル化メカニズムを実装し、タイプに関係なく、配列の各コンポーネントを同じシリアル化メソッドに渡すことができます。

2つの特殊なケースがあります:null参照とプリミティブ配列への参照。

Null参照によりinstanceoffalseになりますが、isArrayNullPointerExceptionをスローします。

プリミティブ配列に適用すると、右側のオペランドのコンポーネントタイプがコンポーネントタイプと完全に一致しない限り、instanceoffalseを生成します。対照的に、isArray()は、すべてのコンポーネントタイプに対してtrueを返します。

199
erickson

後者の場合、objがnullの場合、NullPointerExceptionは返されず、falseが返されます。

32
Burkhard

objの型がint[]の場合、配列はClassになりますが、Object[]のインスタンスにはなりません。 objで何をしたいですか。キャストする場合は、instanceofを使用します。リフレクションを使用する場合は、.getClass().isArray()を使用します。

最近、GroovyアプリケーションをJDK 5からJDK 6にアップグレードする際に問題が発生しました。JDK6でisArray()を使用すると失敗しました。

MissingMethodException:
No signature of Sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...

instanceof Object[]に変更すると、これが修正されました。

5
dturanski

getClass().isArray()は、IBMよりもSun Java 5または6 JREで大幅に遅くなります。

Sun JVMではclazz.getName().charAt(0) == '['を使用する方が高速です。

4

Java配列リフレクションは、「instanceof」を実行できるクラスのインスタンスがない場合に使用します。たとえば、JPAのようにクラスの新しいインスタンスに値を注入する何らかの注入フレームワークを作成している場合、isArray()機能を使用する必要があります。

12月の初めにこのことについてブログを書きました。 http://blog.adamsbros.org/2010/12/08/Java-array-reflection/

3

反射型ソリューションと非反射型ソリューションのどちらかを選択できる場合は、反射型ソリューション(クラスオブジェクトを含む)を選択しないでください。 「間違っている」などということではありませんが、反射を伴うものは一般にあまり明確ではなく、あまり明確ではありません。

2
Bill K

明らかなヌルの場合を除いて、2つの間に見られる動作の違いはありません。どちらのバージョンを優先するかについては、2番目のバージョンを使用します。これはJavaでこれを行う標準的な方法です。

コードの読者を混乱させる場合(String[] instanceof Object[]がtrueであるため)、コードレビューアが質問を続けている場合は、最初のコードをより明確に使用することをお勧めします。

0
hazzen