Подтвердить что ты не робот

Явный vs неявный вызов toString

Я использовал неявный вызов toString, когда вам нужна некоторая отладочная информация об объекте, потому что в случае, если объект имеет значение null, он не генерирует исключение.

Например:

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

вместо:

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

Есть ли какая-либо разница, кроме нулевого случая?
Может ли последний случай работать, когда первый не делает?

Edit:
Что именно делается, в случае неявного вызова?

4b9b3361

Ответ 1

Там небольшая разница. Используйте ту, которая короче и работает чаще.

Если вы действительно хотите получить строковое значение объекта по другим причинам и хотите, чтобы он был нулевым, сделайте следующее:

String s = String.valueOf(obj);

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

В обоих случаях они компилируются примерно так:

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

Если ваш toString() неявный, вы увидите, что во втором добавлении.

Если вы посмотрите на исходный код на 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() сами, вы обходите нулевую проверку и стек стека и переходите прямо к этому в StringBuilder:

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

Итак... очень похожие вещи происходят в обоих случаях. Просто нужно немного поработать.

Ответ 2

Как говорили другие, используйте метод "" + obj.

Согласно Java Language Spec:

  • Если этот термин равен нулю, используйте "null"
  • Примитивные типы преобразуются с использованием конструктора boxed type new Boolean(X) или любого другого
  • toString() вызывается (или эквивалентно)
  • Если результат toString() равен null, используйте "null"
  • Объединить строки.

Ответ 3

Никакой разницы, кроме, как вы говорите, нет нулевой безопасности. Всегда предпочитайте первое для последнего.

Ответ 4

Собственно, если ваш инвариант говорит, что объект никогда не должен быть нулевым, это не имеет значения. Это зависит от того, принимаете ли вы obj равным null.

Ответ 5

Очень просто написать общий ссылочный тип.

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