Почему метод toString() работает по-разному между объектом Array и ArrayList в Java

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

на list [a, b, c] выводится, в то время как для array какой-то адрес-это выход. Когда мы хотим вывести array значения, мы можем использовать Arrays.toString(array);, который работает так же, как list.

Я просто удивляюсь, почему мы не можем позвонить toString() непосредственно на array чтобы получить значения. Разве это не более интуитивно и удобно? Что приводит к различным методам лечения на Array и ArrayList?

6 ответов


основное различие между массивом и arraylist заключается в том, что arraylist-это класс, написанный на Java и имеющий свою собственную реализацию (включая решение переопределить toString), тогда как массивы являются частью спецификации языка. В частности,JLS 10.7 гласит:

члены типа массива являются следующие:

  • публичная конечная длина поля
  • публичный метод clone, который переопределяет метод с тем же именем в объекте класса и не создает проверенных исключений.
  • все члены, унаследованные от класса Object; единственный метод Object, который не наследуется, - это его метод clone.

другими словами, спецификация языка предотвращает toString метод массива для переопределения и поэтому использует реализацию по умолчанию, определенную в Object, который печатает имя класса и хэш-код.

почему это решение было принято, это вопрос, который, вероятно, следует задать разработчикам языка...


мне просто интересно, почему мы не можем вызвать toString() непосредственно на массив, чтобы получить значение.

на самом деле toString метод вызывается на объекте array. Но, поскольку тип массива не переопределяет toString метод Object class, поэтому реализация по умолчанию toString вызывается, что возвращает представление формы, которую вы видите.

представление имеет вид: -

[typeOfArray@hashCode

в вашем случае это что-то вроде: -

[Ljava.lang.String;@3e25a5

тогда как, в случае ArrayList экземпляров, переопределении toString метод ArrayList класса вызывается.


короткий ответ заключается в том, что toString определяется в нескольких разных местах с разным поведением.

класс Arrays определяет toString как статический метод, который будет вызываться как

Arrays.toString(arr_name);

но класс Arrays также наследует нестатический метод toString от класса Object. Поэтому, если вызывается экземпляр, он вызывает Object.метод toString, который возвращает строковое представление объекта (например: [Ljava.ленг.Объект;@4e44ac6a)

Так Матрицы.toString () и MyObject.toString () вызывают разные методы с одинаковым именем.

класс ArrayList наследует toString от класса AbstractCollection, где он является нестатическим методом, поэтому его можно вызвать для объекта, например:

MyArrayList.toString();

поскольку это строковое представление коллекции, а не объекта, результатом являются значения в удобочитаемом формате, например [один, два].


потому что при печати toString(), он будет печатать по умолчанию className@HashCode.

Итак, когда вы печатаете array тогда выше будет напечатано.

но ArrayList расширенных от AbstractCollection класс и где toString() метод переопределен, как показано ниже

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

который печатает читаемый формат


это вызов метода toString для ArrayList. Но для массивов вы не можете найти такое.

 /**
 * 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(' ');
    }
}

на array toString () метод он печатает адрес памяти. Но в ArrayList этот класс переопределяет Object toString () метод .

toString() реализация ArrayList

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

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