2012-01-18 9 views
7

Tôi đang viết một phương thức in mọi đối tượng mà nó nhận được. Điều này hoạt động tốt bằng cách gọi phương thức Object.toString() cho đối tượng nhưng không hoạt động đối với mảng. Tôi có thể tìm hiểu xem nó là một mảng với phương pháp Object.getClass().isArray(), nhưng tôi không biết làm thế nào để đúc nó.In các mảng trong 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)); 

Trả lời

12

Nếu bạn không biết loại bạn có thể truyền đối tượng sang Object[] và in nó như thế này (sau khi đảm bảo nó thực sự là một mảng và có thể được đúc thành Object[]). Nếu nó không phải là một thể hiện của Object[] sau đó sử dụng phản ánh để tạo ra một đầu tiên Object[] và sau đó in:

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)); 
     } 
    } 
} 

KIỂM TRA:

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

OUTPUT:

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

Làm cách nào để tìm hiểu xem đó có phải là mảng nguyên thủy không? Ngoài ra tôi cần phải biết loại nguyên thủy của mảng. – multiholle

+0

@multiholle - Xem chỉnh sửa của tôi. –

+0

Xin vui lòng kiểm tra mã cập nhật, nó sẽ ** bây giờ in bất kỳ đối tượng mảng nào ** mà không cần bạn truyền đến mọi kiểu nguyên thủy trong một chuỗi xấu của 'if/elseif/else' – anubhava

1

Nếu bạn hỏi cách gọi phương thức này theo cách lập trình trên bất kỳ mảng nào, sẽ không thể thực hiện được với các mảng nguyên thủy. Nhìn vào các tài liệu cho lớp Arrays, bạn sẽ thấy có quá tải toString() cho mọi loại mảng nguyên thủy.

Điều này là do int[] ví dụ: mở rộng Object thay vì Object[].

EDIT: đây là một giải pháp đáng tiếc longwinded để bao gồm các mảng nguyên thủy:

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); 
} 

Tôi hy vọng ai đó có thể cung cấp một giải pháp thanh lịch hơn, nhưng dựa trên những hạn chế của mảng nguyên thủy, điều này có thể là điều tốt nhất bạn có thể làm.

-2

Nếu tất cả những gì bạn muốn làm là in nó ra thành một String, tại sao lại chọn nó? Chỉ cần coi nó như là một mảng của các đối tượng, lặp qua mảng, và gọi phương thức toString() trên mỗi đối tượng.

+0

Nhưng tôi không thể đưa nó vào một mảng 'Đối tượng' nếu nó chứa các kiểu nguyên thủy. – multiholle

1

Tại sao bạn không để method overloading giải quyết vấn đề của mình? Đơn giản chỉ cần viết hai (hoặc nhiều hơn) các phương pháp có cùng tên nhưng chữ ký khác nhau và sau đó cho phép trình biên dịch quyết định phương pháp sẽ được gọi khi chương trình thực hiện:

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)); 
} 

sử dụng Ví dụ ở những nơi khác trong các mã:

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

Bạn cần sử dụng sự phản chiếu để đi đến cấu trúc sâu hơn của một đối tượng nếu bạn không muốn dựa vào lớp của đối tượng để làm quá tải phương thức toString của đối tượng (để có được một cái gì đó hữu ích hơn in tên lớp và mã băm ...)

Đề xuất của tôi n là sử dụng một thư viện có sử dụng phản ánh để có được cấu trúc sâu hơn, chẳng hạn như 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"] 
} 

này in mảng dàng, bao gồm các mảng đa chiều và mảng nguyên thủy.

Nhưng lợi ích thực sự là nó in các đối tượng của bất kỳ lớp nào một cách thống nhất, cho dù lớp có overriden toString trong bất kỳ cách hữu ích hay không.