web-dev-qa-db-ja.com

toStringの明示的呼び出しと暗黙的呼び出し

オブジェクトがnullの場合、例外をスローしないため、オブジェクトに関するデバッグ情報が必要な場合は、toStringの暗黙的な呼び出しを使用していました。

例えば:

System.out.println("obj: "+obj);

の代わりに:

System.out.println("obj: "+obj.toString());

帰無仮説以外に違いはありますか?
前者が機能しない場合、後者のケースは機能しますか?

編集:
暗黙の呼び出しの場合、正確には何が行われますか?

36
Burkhard

少し違いがあります。短く、より頻繁に機能するものを使用してください。

他の理由で実際にオブジェクトの文字列値を取得し、それをnullフレンドリにしたい場合は、次のようにします。

_String s = String.valueOf(obj);
_

編集:質問が拡張されたので、回答を拡張します。

どちらの場合も、次のようにコンパイルされます。

_System.out.println(new StringBuilder().append("obj: ").append(obj).toString());
_

toString()が暗黙的である場合、2番目の追加でそれを確認できます。

Javaのソースコードを見ると、StringBuilder.append(Object)は次のようになっていることがわかります。

_public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}
_

ここで、_String.valueOf_は次のようになります。

_public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}
_

ここで、自分でtoString()を実行すると、nullチェックとスタックフレームをバイパスして、StringBuilderでこれに直接進みます。

_public StringBuilder append(String str) {
    super.append(str);
    return this;
}
_

つまり...どちらの場合も非常によく似たことが起こります。もう少し作業をするだけです。

54
Dustin

他の人が言っているように-_"" + obj_メソッドを使用します。

Java言語仕様 によると:

  • 用語がnullの場合は、_"null"_を使用します
  • プリミティブ型は、ボックス型コンストラクターnew Boolean(X)などを使用して変換されます
  • toString()が呼び出されます(または同等のもの)
  • toString()resultnullの場合、_"null"_を使用します
  • 文字列を連結します。
3
Draemon

実際、不変条件がオブジェクトがnullであってはならないと言っている場合、それは問題ではありません。したがって、objをnullとして受け入れるかどうかによって異なります。

1
Pål GD

あなたが言うように、ヌルの安全性を除いて違いはありません。常に前者を後者よりも好む。

1
cletus

一般的な参照型を書くのは非常に簡単です。

class ref
{
  static public class Reference<T>
  {
    private T value;
    public Reference(T value) { set(value); }
    public Reference() { set(null); }
    public void set (T value) { this.value = value; }
    public T get () { return this.value; }
    public String toString() { return String.valueOf(this.value); }
  }

  static void fillString (Reference<String> str)
  {
    str.set("foo");
  }

  public static void main (String[] args)
  {
    Reference<String> str = new Reference<String>("");
    fillString(str);
    System.out.println (str);
  }
}

それを実行すると、必要な出力が得られます。

javac ref.Java && Java ref
foo
0
ceving