2013-05-07 19 views
12

だから私は配列であるかもしれないオブジェクトを持っています。プリミティブでも、文字列でもかまいません。配列の場合、それは文字どおりの配列になります。オブジェクトを配列にキャスト

配列であるかどうかはわかりませんが、値を取得するために反復処理できるものにキャストできないようです。

// o is an object and clazz is the class of the o 
if (clazz == Array.class) { 
      Class ofArray = o.getClass().getComponentType(); 
      String arrayType = ofArray.getName(); // 'Double' for my test case 
      //ERROR: [D cannot be cast to [Ljava.lang.Object 
      Object[] objects = (Object[]) o; 
    } 

私の背景はルビーとphp(ちょうどうまくいくでしょう)と静的なタイピングは私の頭を乱しています。何か案は?

EDIT:

これは

[D cannot be cast to [Ljava.lang.Object. 

エラーをスローし、私は何をしないのですか?

if (o.getClass().isArray()) { 
    Object[] objects = (Object[]) o; 
} 
+0

オブジェクトが配列かどうかをテストできます。この質問はそれに対処しています:http://stackoverflow.com/questions/219881/java-array-reflection-isarray-vs-instanceof次に、あなたは安全にキャストし、それを反復することができます。 – Marvo

+0

私の例のキャストはなぜ機能しないのですか? –

+0

わかりませんが、おそらくその特定のオブジェクトは配列ではありませんでした。 'clazz == Array.class'おそらくいくつかの非配列オブジェクトを通過させます。 – Marvo

答えて

19

あなたは、このように行うことができるすべてのプリミティブ型のためにスイッチを作りたくない場合:あなたのコードを使用している2つの異なる場所でループにしたくない場合は :

if (ofArray.isPrimitive()) { 
    int length = Array.getLength(o); 
    for (int i = 0; i < length; i++) { 
     Object obj = Array.get(o, i); 
     System.out.println(obj); 
    } 
} 
else { 
    Object[] objects = (Object[]) o; 
    for (Object obj : objects) { 
     System.out.println(obj); 
    } 
} 

編集プリミティブ配列をオブジェクト配列に変換するこのメソッド:

static Object[] convertToObjectArray(Object array) { 
    Class ofArray = array.getClass().getComponentType(); 
    if (ofArray.isPrimitive()) { 
     List ar = new ArrayList(); 
     int length = Array.getLength(array); 
     for (int i = 0; i < length; i++) { 
      ar.add(Array.get(array, i)); 
     } 
     return ar.toArray(); 
    } 
    else { 
     return (Object[]) array; 
    } 
} 
+1

これはうまくいきますが、暗黙のボクシング操作がここで起こっています: 'Array.get(o、i)' - 言い換えれば、 'int'型の要素が' Integer'型に変換され、 double'は 'double'に変換されます。これは長期的には非効率的になる可能性があります –

+0

ええ、彼は効率を望む場合には良い点です。 – Vegard

+0

素晴らしい! – Hartmut

1

これはObjectのsublcassesである要素を持つ配列のために動作します:

if (clazz.isArray()) { 
    Object[] objects = (Object[]) o; 
    for (Object obj : objects) 
     System.out.println(obj); 
} 

あなたは(AB)instanceofを使用することができ、特定の配列型ではなくたとえば、アレイをキャストする必要がある場合内容をストリングとして印刷するだけで、Object[]で十分です。配列がプリミティブ型である場合

UPDATE

、あなたが各1と正しいタイプへのキャストをテストせざるを得ない場合には、Object[]は、この場合は動作しません - が、そこではありませんその Javaの多くのプリミティブ型は、巨大なスイッチではありません:)これは私が何を意味するかです:

if (clazz.isArray()) { 
    if (clazz.getComponentType().equals(double.class)) { 
     double[] numbers = (double[]) o; 
     for (double d : numbers) 
      System.out.println(d); 
    } 
} 
+0

回答ありがとうございますが、まだ動作していません。更新された質問をチェックしてください。 –

+1

エラーが発生した行はどの行ですか?上記のコードは完璧に動作し、問題は他の場所にある必要があります –

+0

キャストでエラーが発生しています。 (2行目)テスト配列のコンポーネントタイプを 'double'から対応するラッパー 'Double'に変更した場合、エラーは発生しないことに気付きました。 –

0

それはあなたのObjectが配列である知っているだけでは十分ではないのです - あなたはまた、配列の要素の基になる型を知っている必要があります。

Object[] objects = (Object[]) o; 
+0

はい、これはプリミティブのタイプを知らなくても可能ですか? (巨大なスイッチを書かずに) –

+1

あなたがJavaを使っている方法は、言及したようなスクリプト言語では非常に一般的です:php、ruby。 Javaのような静的型付けされた言語では、これはおそらく何らかの形で達成されるかもしれませんが、遅くなり、良いコーディングとはみなされません。 – fjf2002

+0

より一般的な問題の概要を説明して、Javaでの対処方法に関する一般的なヒントを得ることができます。オブジェクト型を使用して配列、文字列、およびその他の型をメソッドに渡すことはお勧めできません。 – fjf2002

1

をあなたはObject[]

if (clazz == Array.class) { 
    Class ofArray = o.getClass().getComponentType(); 
    // String arrayType = ofArray.getName(); // 'Double' for my test case 
    if (ofArray instanceof double.class) 
    double[] doubles = (double[]) o; 
    for (double d: doubles) 
    System.out.println(d); 
} 
にプリミティブの配列をキャスト入力することはできません:あなたの配列要素は、プリミティブ型である doubleを言うならば、あなたは

double[] doubleArray = (double[]) o; 

にこれは動作しません必要

を作成する場合は、instanceofチェックなし

if (!(o instanceof Object[])) { 
    int len = Array.getLength(o); 
    Object[] objects = new Object[len]; 
    for (int i = 0; i < len; i++) 
    objects[i] = Array.get (o, i); 
    for (Object obj: objects) 
    System.out.println(obj); 
} 
+0

2番目のバージョンはまさに私が望んでいたものでした!私はデバッグ出力の効率を必要としません、簡潔さだけ! – Xerus

関連する問題