2008-11-30 10 views
29

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

Например:

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

вместо:

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

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

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

ответ

49

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

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

String s = String.valueOf(obj); 

Edit: Вопрос был расширен, так что я Я продолжу свой ответ.

В обоих случаях они компилировать что-то вроде следующего:

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

Когда toString() подразумевается, вы увидите, что во втором Append.

Если вы посмотрите на исходный код на 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; 
} 

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

1

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

+0

почему он предпочтительно использовать последнюю версию? спасибо – Bartzilla 2013-01-03 00:14:01

3

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

По данным Java Language Spec:

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

4-й пункт в вашем списке вызвал мой интерес. Для вещей, которые не являются строками, он добавляет String.valueOf (String.valueOf (ob)). Это дешево и соответствует требованиям, я полагаю. – Dustin 2008-11-30 09:44:46

+0

heh - отличный. Если честно, я не знал, пока не посмотрю на спецификацию - различие никогда не имело значения. Хороший пример того, почему я всегда могу перейти к первому источнику, если смогу. – Draemon 2008-11-30 09:58:15

1

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

0

Весьма легко написать общий ссылочный тип.

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 
Смежные вопросы