2012-01-18 15 views
7

渡されたすべてのオブジェクトを出力するメソッドを作成しています。これは、オブジェクトのObject.toString()メソッドを呼び出すことによって正常に動作しますが、配列では機能しません。私はそれがObject.getClass().isArray()メソッドを持つ配列かどうかを調べることができますが、キャストする方法はわかりません。Javaで配列を印刷する

int[] a; 
Integer[] b; 

Object aObject = a; 
Object bObject = b; 

// this wouldn't work 
System.out.println(Arrays.toString(aObject)); 
System.out.println(Arrays.toString(bObject)); 

答えて

12

タイプがわからない場合は、オブジェクトをObject[]にキャストして、このように印刷してください(実際には配列であり、Object[]にキャストできます)。それはObject[]のインスタンスでない場合、Object[]第1及びプリントを作成する反射を使用:

private void printAnyArray(Object aObject) { 
    if (aObject.getClass().isArray()) { 
     if (aObject instanceof Object[]) // can we cast to Object[] 
      System.out.println(Arrays.toString((Object[]) aObject)); 
     else { // we can't cast to Object[] - case of primitive arrays 
      int length = Array.getLength(aObject); 
      Object[] objArr = new Object[length]; 
      for (int i=0; i<length; i++) 
       objArr[i] = Array.get(aObject, i); 
      System.out.println(Arrays.toString(objArr)); 
     } 
    } 
} 

テスト:

printAnyArray(new int[]{1, 4, 9, 16, 25}); 
printAnyArray(new String[]{"foo", "bar", "baz"}); 

OUTPUT:

[1, 4, 9, 16, 25] 
[foo, bar, baz] 
+0

プリミティブアレイであるかどうかはどうすればわかりますか?また、私は配列のプリミティブ型を知る必要があります。 – multiholle

+0

@multiholle - 私の編集を参照してください。 –

+0

Plsは更新されたコードをチェックします。これで、** if/elseif/elseの醜いチェーンのすべてのプリミティブ型にキャストする必要なしに**配列オブジェクト**を出力します。 – anubhava

1

このメソッドをどの配列でもプログラム的に呼び出す方法をご希望の場合は、プリミティブ配列では不可能です。 Arraysクラスのドキュメントを見ると、プリミティブ配列タイプごとにtoString()のオーバーロードがあることがわかります。

Object[]ではなく、int[]がたとえばObjectに拡張されているためです。

EDIT:ここプリミティブ配列を含むように残念ながらlongwindedソリューションです:

public static void printObject(Object obj) { 

    String output; 

    if (obj == null) { 
     output = "null"; 
    } 
    else if (obj.getClass().isArray()) { 

     if (obj instanceof Object[]) { 
      output = Arrays.toString((Object[])obj); //Object[] overload 
     } 
     else if (obj instanceof int[]) { 
      output = Arrays.toString((int[])obj); //int[] overload 
     } 
     //and so on for every primitive type 
    } 
    else { 
     output = obj.toString(); 
    } 

    System.out.println(output); 
} 

私は他の誰かがよりエレガントなソリューションを提供することができます願っていますが、プリミティブ配列の制限に基づいて、これはあるかもしれませんあなたができる最高のもの。

-2

あなたがしたいことは、文字列としてプリントすることです。なぜそれをキャストしますか?これをObjectの配列として扱い、配列を繰り返し処理し、各ObjectのtoString()メソッドを呼び出します。

+0

しかし、プリミティブ型が含まれていれば 'Object'配列にキャストできません。 – multiholle

1

method overloadingはあなたの問題を解決させてどうでしょうか?単純に2つ(またはそれ以上)と同じ名前のメソッドが異なるシグネチャを書き込み、その後、コンパイラは、プログラムが実行されるときに呼び出される方法を決定しましょう:他の場所コードで

void print(Object object) { 
    System.out.println("Object: " + object); 
} 

void print(Object[] array) { 
    System.out.println("Object[]: " Arrays.toString(array)); 
} 

void print(int[] array) { 
    System.out.println("int[]: " Arrays.toString(array)); 
} 

使用例:

String first = "test"; 
print(first); // prints "Object: test"; 

String[] second = {"A", "B"};  
print(second); // prints "Object[]: [A, B]" 

int[] third = {1, 2}; 
print(third); // prints "int[]: [1, 2]" 
0

ObjectのtoStringメソッドをオーバーロードするためにオブジェクトのクラス自体に頼りたくない場合は、リフレクションを使用してオブジェクトのより深い構造に到達する必要があります(クラス名とハッシュコードを印刷するよりも便利です... )

私の提案Nは、GSONとして、より深い構造に到達するためにリフレクションを使用してライブラリーを使用することである:http://code.google.com/p/google-gson/

public static String print(Object object) { 
    return new Gson().toJson(object); 
} 

public static void test() { 
    System.out.println(print(new int[][] {new int[] {1, 2, 3} })); 
    // outputs: [[1,2,3]] 
    System.out.println(print(new String[] { "aa", "bb", "cc" })); 
    // outputs: ["aa","bb","cc"] 
} 

これは多次元配列とプリミティブアレイを含む、難なくアレイを印刷します。

しかし、実際のメリットは、クラスがtoStringを便利な方法でオーバーライドしているかどうかにかかわらず、すべてのクラスのオブジェクトを一様に印刷することです。