Почему метод 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(", ");
}
}