2011-02-04 7 views
32

Classのインスタンスがある場合、その配列タイプのClassインスタンスを取得する方法はありますか?私は基本的にのために求めていることはgetComponentType()方法の逆である方法getArrayTypeのと同等である、そのようなこと:あなたは通常、次の配列の取得コンポーネントタイプのクラス

array.getClass() == 
    Array.newInstance(array.getClass().getComponentType(), 0).getClass() 

を行うことができます

array.getClass().getComponentType().getArrayType() == array.getClass() 

答えて

43

一つのことです。

ところで、これは動作するように表示されます。ここでは

Class clazz = Class.forName("[L" + componentType.getName() + ";"); 

はテストです。これはtrueを印刷:

Integer[] ar = new Integer[1]; 
Class componentType = ar.getClass().getComponentType(); 
Class clazz = Class.forName("[L" + componentType.getName() + ";"); 

System.out.println(clazz == ar.getClass()); 

The documentation of Class#getName()は厳密に配列クラス名の形式を定義:

このクラスオブジェクトが配列のクラスを表す場合、その名前の内部形式は、名前から成ります配列のネストの深さを表す1つ以上の '['文字で始まる要素型。

Class.forName(..)アプローチ直接かかわらプリミティブのために動作しません - 彼らのためにあなたは、名前(int)と配列速記の間のマッピングを作成する必要があるだろうが - (I

+0

最初のve rsion( 'Array.newInstance(...)。getClass()'を使って)*は*プリミティブのために働きます。 – finnw

+0

はい、私のポイントは2番目のものではありませんでした。 – Bozho

+0

これはとても役に立ちます、ありがとう。私の目的のために、私はプリミティブを扱う必要がないのでどちらのアプローチも使用可能です。 –

6

、あなたは「ドンタイプを知る必要がある場合は、配列を作成したいだけです。

java.lang.reflect.Array.newInstance(componentType, 0).getClass(); 

しかし、それは不要なインスタンスを作成します頭に浮かぶ

1

別の可能なリファクタリングがありますジェネリックスーパークラスを使用して、2つのクラスオブジェクトをコンストラクタに渡します。

サブクラスで次に
protected AbstractMetaProperty(Class<T> valueClass, Class<T[]> valueArrayClass) { 
    this.valueClass = valueClass; 
    this.valueArrayClass = valueArrayClass; 
} 

public IntegerClass() { 
    super(Integer.class, Integer[].class); 
} 

次に抽象クラスであなたがvalueClass.cast(x)valueArrayClass.isInstance(x)など

9

実際に起因するClassLoaderに、プリミティブと多次元配列を使用することができ、答えは少し複雑です:

public static Class<?> getArrayClass(Class<?> componentType) throws ClassNotFoundException{ 
    ClassLoader classLoader = componentType.getClassLoader(); 
    String name; 
    if(componentType.isArray()){ 
     // just add a leading "[" 
     name = "["+componentType.getName(); 
    }else if(componentType == boolean.class){ 
     name = "[Z"; 
    }else if(componentType == byte.class){ 
     name = "[B"; 
    }else if(componentType == char.class){ 
     name = "[C"; 
    }else if(componentType == double.class){ 
     name = "[D"; 
    }else if(componentType == float.class){ 
     name = "[F"; 
    }else if(componentType == int.class){ 
     name = "[I"; 
    }else if(componentType == long.class){ 
     name = "[J"; 
    }else if(componentType == short.class){ 
     name = "[S"; 
    }else{ 
     // must be an object non-array class 
     name = "[L"+componentType.getName()+";"; 
    } 
    return classLoader != null ? classLoader.loadClass(name) : Class.forName(name); 
} 
+1

最後の行では、クラスローダーパラメータでforNameメソッドを使用することもできます(これは 'null'の場合も同様です)ので、大文字と小文字の区別はありません。 –

関連する問題