web-dev-qa-db-ja.com

Java内のArrayオブジェクトとArrayListオブジェクトの間でtoString()メソッドの動作が異なる理由

_    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の値を出力する場合は、listと同じように機能するArrays.toString(array);を使用できます。

値を取得するためにarraytoString()を直接呼び出すことができないのはなぜですか。そうする方が直感的で便利ではありませんか? ArrayArrayListの扱いが異なるのはなぜですか。

14
Terry Li

配列とarraylistの主な違いは、arraylistがJavaで記述されたクラスであり、独自の実装(toStringをオーバーライドする決定を含む)がある)ですが、配列特に JLS 10.7 は、言語仕様自体の一部です。

配列型のメンバーは次のすべてです。

  • パブリック最終フィールド長
  • Publicメソッドclone。Objectクラスの同じ名前のメソッドをオーバーライドし、チェック例外をスローしません。
  • クラスObjectから継承されたすべてのメンバー。継承されないObjectの唯一のメソッドは、そのcloneメソッドです。

言い換えると、言語仕様は配列のtoStringメソッドがオーバーライドされるのを防ぎ、したがって、クラス名とハッシュコードを出力するObjectで定義されたデフォルトの実装を使用します。

この決定がなされた理由は、おそらく言語の設計者に尋ねられるべき質問です...

15
assylias

配列に対してtoString()を直接呼び出して値を取得できないのはなぜですか。

実際には、配列オブジェクトでtoStringメソッドが呼び出されます。ただし、配列タイプはtoStringクラスのObjectメソッドをオーバーライドしないため、toStringのデフォルト実装が呼び出され、表示されるフォームの表現が返されます。

表現は次の形式です:-

[typeOfArray@hashCode

あなたの場合、それは次のようなものです:-

[Ljava.lang.String;@3e25a5

一方、ArrayListインスタンスの場合、toStringクラスのオーバーライドされたArrayListメソッドが呼び出されます。

4
Rohit Jain

短い答えは、toStringがいくつかの異なる場所で定義されており、動作が異なるためです。

Arraysクラスは、toStringを静的メソッドとして定義します。

Arrays.toString(arr_name);

ただし、Arraysクラスは、Objectクラスから非静的メソッドtoStringも継承します。したがって、インスタンスで呼び出されると、オブジェクトの文字列表現を返すObject.toStringが呼び出されます(例:[Ljava.lang.Object; @ 4e44ac6a)

したがって、Arrays.toString()とMyObject.toString()は、同じ名前の異なるメソッドを呼び出しています。

ArrayListクラスは、非静的メソッドであるAbstractCollectionクラスからtoStringを継承しているため、次のようにオブジェクトで呼び出すことができます。

MyArrayList.toString();

これはオブジェクトではなくコレクションの文字列表現であるため、結果は[1、2]のような読み取り可能な形式の値になります。

3
danf

toString()を出力すると、デフォルトで_className@HashCode_が出力されるためです。

したがって、arrayを印刷すると、上記が印刷されます。

ただし、ArrayListAbstractCollectionクラスによって拡張され、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(' ');
        }
    }
_

ArrayListオブジェクトの読み取り可能な形式を出力します。

0
Bhavik Ambani

これは、ArrayListのtoStringメソッド呼び出しです。しかし、配列の場合、そのようなものを見つけることはできません。

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