我有一个班级
class Configuration {
// various stuff
@Override
public String toString() {
// assemble outString
return outString;
}
}
我还有另一个班级
class Log {
public static void d(String format, Object... d) {
// print the format using d
}
}
Log类工作得非常好,我一直都在使用它。现在当我这样做时:
Configuration config = getConfiguration();
Log.d(config);
我收到编译错误The method d(String, Object...) in the type Log is not applicable for the arguments (Configuration)
。我可以解决这个问题:
Log.d("" + config); // solution 1
Log.d(config.toString()); // solution 2
我的问题:这有什么不同?在第一个解决方案中,编译器注意到它必须连接两个字符串,但第二个是配置。所以Configuration#toString()
被调用,一切都很好。在编译器错误情况下,编译器发现需要一个String,但是给出了一个Configuration。基本上是同样的问题。
这些案例有何不同,为什么toString
没有被调用?
答案 0 :(得分:11)
在设计语言时,有人决定当程序员使用+运算符将任意对象附加到字符串时,他们肯定需要String
,因此隐式调用toString()
是有道理的。
但是如果你调用一个带有String
其他东西的任意方法,那只是一个类型错误,正是所有静态类型所谓的要防止的。
答案 1 :(得分:3)
该行
"" + config
被翻译成类似
的内容StringBuilder sb = new StringBuilder("");
sb.append(config);
第二行调用
StringBuilder.append(Object obj);
此方法调用obj.toString()
以获取对象的String表示。
另一方面,Log.d
的第一个参数必须是String,在这种情况下,Java不会自动调用toString()
将所有内容强制转换为String。
答案 2 :(得分:2)
在一种情况下,您将对象参数传递给期望对象的运算符。
在前面的例子中,您将对象参数传递给期望字符串的函数。
基本上功能/操作员签名是不同的。
在这个问题的上下文中,几乎是附带的.tostring在应用+时调用。它需要一个对象并做一些事情。
就你所知,你可能在错误地需要字符串时传入对象。所以它不能盲目地做.tostring()
答案 3 :(得分:2)
toString()
的常见用法之一,是print()
的{{1}}和println()
方法,如:
PrintStream
基本上,这两个方法将在传递的对象上调用System.out.print(object);
System.out.println(object);
。这是Polymorphism的好处之一。
答案 4 :(得分:2)
好问题......
但是, 编译器不会调用方法来匹配形式参数。它只是尝试在可能的情况下施放物体。
但是当你使用“+”运算符时,编译器默认执行其参数的toString()方法(如果它们是对象)。
答案 5 :(得分:1)
You are passing Configuration class object argument in case 1 but in the case 2 , you are passing string argument . so no error occures
。