2012-12-08 18 views
10
String[] array = {"a","c","b"}; 
    ArrayList<String> list = new ArrayList<String>(); 
    list.add("a"); 
    list.add("b"); 
    list.add("c"); 
    System.out.println(array); 
    System.out.println(list); 

Đối list[a, b, c] là đầu ra trong khi đối với array một số địa chỉ được hiển thị. Khi chúng tôi muốn xuất các giá trị array, chúng tôi có thể sử dụng Arrays.toString(array); hoạt động giống như list.Tại sao phương thức toString() hoạt động khác nhau giữa mảng và đối tượng ArrayList trong Java

Tôi tự hỏi tại sao chúng tôi không thể gọi số toString() trực tiếp trên array để nhận các giá trị. Không phải là nó trực quan và thuận tiện hơn để làm như vậy? Kết quả của các phương pháp điều trị khác nhau trên ArrayArrayList là gì?

Trả lời

11

Sự khác biệt chính giữa mảng và danh sách mảng là danh sách mảng là một lớp được viết bằng Java và có triển khai riêng (bao gồm cả quyết định ghi đè toString) trong khi mảng là một phần của đặc tả ngôn ngữ. Đặc biệt, JLS 10.7 trạng thái:

Các thành viên của một loại mảng là tất cả những điều sau đây:

  • Chiều dài lĩnh vực thức công
  • Phương pháp nào clone, mà sẽ ghi đè phương pháp của cùng tên trong lớp Object và ném không có ngoại lệ kiểm tra.
  • Tất cả các thành viên được kế thừa từ đối tượng lớp; phương pháp duy nhất của đối tượng không được kế thừa là phương thức sao chép của nó.

Nói cách khác đặc tả ngôn ngữ ngăn chặn các phương pháp toString của một mảng được overriden và do đó nó sử dụng các cài đặt mặc định theo quy định tại Object mà in tên lớp và hashcode.

Tại sao quyết định này đã được thực hiện là một câu hỏi mà có lẽ nên được yêu cầu các nhà thiết kế của ngôn ngữ ...

+0

Xem thêm [câu trả lời này] (http://stackoverflow.com/a/10295995/829571). – assylias

4

Tôi tự hỏi tại sao chúng tôi không thể gọi toString() trực tiếp trên mảng để nhận được các giá trị.

Phương thức thực tế là toString được gọi trên đối tượng mảng. Tuy nhiên, vì kiểu mảng không ghi đè phương thức toString từ lớp Object, do đó, việc triển khai mặc định toString được gọi, trả về biểu thị của biểu mẫu mà bạn thấy.

Các đại diện có dạng: -

[[email protected] 

Trong trường hợp của bạn đó là cái gì đó như: -

[Ljava.lang.String;@3e25a5 

Trong khi đó, trong trường hợp ArrayList trường hợp, overriden toString phương pháp trong ArrayList lớp là được viện dẫn.

0

Bởi vì khi bạn in toString(), nó sẽ bằng cách in mặc định [email protected].

Vì vậy, khi bạn in array thì ở trên sẽ được in.

Nhưng ArrayList được extened bởi AbstractCollection lớp và nơi mà các phương pháp toString() được overriden như sau

public String toString() { 
     Iterator<E> it = iterator(); 
     if (! it.hasNext()) 
      return "[]"; 

     StringBuilder sb = new StringBuilder(); 
     sb.append('['); 
     for (;;) { 
      E e = it.next(); 
      sb.append(e == this ? "(this Collection)" : e); 
      if (! it.hasNext()) 
       return sb.append(']').toString(); 
      sb.append(',').append(' '); 
     } 
    } 

mà in định dạng có thể đọc được của đối tượng ArrayList.

-1

Đối với phương thức arraytoString() nó sẽ in địa chỉ bộ nhớ. Nhưng trong ArrayList, lớp này sẽ ghi đè phương thức ObjecttoString().

toString() thực hiện ArrayList

0

Đây là toString phương thức gọi cho ArrayList. Nhưng đối với mảng bạn không thể tìm thấy như vậy.

/** 
* Returns a string representation of this collection. The string 
* representation consists of a list of the collection's elements in the 
* order they are returned by its iterator, enclosed in square brackets 
* (<tt>"[]"</tt>). Adjacent elements are separated by the characters 
* <tt>", "</tt> (comma and space). Elements are converted to strings as 
* by {@link String#valueOf(Object)}. 
* 
* @return a string representation of this collection 
*/ 
public String toString() { 
    Iterator<E> it = iterator(); 
    if (! it.hasNext()) 
     return "[]"; 

    StringBuilder sb = new StringBuilder(); 
    sb.append('['); 
    for (;;) { 
     E e = it.next(); 
     sb.append(e == this ? "(this Collection)" : e); 
     if (! it.hasNext()) 
      return sb.append(']').toString(); 
     sb.append(',').append(' '); 
    } 
} 
1

Câu trả lời ngắn gọn là do toString được xác định ở một vài nơi khác nhau, với các hành vi khác nhau.

Lớp Mảng xác định toString như một phương pháp tĩnh, được gọi như

Arrays.toString(arr_name); 

Nhưng lớp Mảng cũng được thừa hưởng phương thức toString không tĩnh từ lớp Object. Vì vậy, nếu được gọi trên một thể hiện, nó sẽ gọi Object.toString trả về một biểu diễn chuỗi của đối tượng (ví dụ: [Ljava.lang.Object; @ 4e44ac6a)

Vì vậy, Arrays.toString() và MyObject.toString() là gọi các phương thức khác nhau có cùng tên.

Lớp ArrayList thừa hưởng toString từ lớp AbstractCollection, nơi mà nó là một phương pháp không tĩnh, vì vậy có thể được gọi trên đối tượng như:

MyArrayList.toString(); 

Bởi vì đó là một chuỗi đại diện của một bộ sưu tập và không phải là một đối tượng , kết quả là các giá trị ở định dạng có thể đọc được như [một, hai].