6

我有一堂课

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()被称为,一切都很好。在编译器错误情况下,编译器发现需要一个字符串,但给出了一个配置。基本上同样的问题。

  • 需要:字符串
  • 给定:配置

这些情况有何不同,为什么toString不调用?

4

6 回答 6

11

在设计语言时,有人决定当程序员使用 + 运算符将任意对象附加到字符串时,他们肯定需要 a String,因此隐式调用toString()是有意义的。

但是如果你调用一个任意的方法来接受一个其他的String东西,那只是一个类型错误,这正是静态类型应该防止的。

于 2012-07-30T08:31:42.187 回答
3

线

"" + config

被翻译成类似的东西

StringBuilder sb = new StringBuilder("");
sb.append(config);

第二行调用的地方

StringBuilder.append(Object obj);

此方法调用obj.toString()以获取对象的字符串表示形式。

另一方面,第一个参数Log.d必须是字符串,在这种情况下,Java 不会自动调用toString()将所有内容转换为字符串。

于 2012-07-30T08:33:43.617 回答
2

在一种情况下,您将对象参数传递给需要对象的运算符。

在较早的情况下,您将对象参数传递给需要字符串的函数。

基本上功能/运算符签名是不同的。

[在这个问题的上下文中] .tostring 在应用 + 时调用几乎是偶然的。它需要一个对象并做某事。

如您所知,当错误地需要字符串时,您可能会传入对象。所以不能一味做 .tostring()

于 2012-07-30T08:29:09.903 回答
2

toString(), isprint()println()的方法的常见用法之一PrintStream,如:

System.out.print(object);
System.out.println(object);

基本上,这两个方法都会调用toString()传递的对象。这是Polymorphism的好处之一。

于 2012-07-30T08:36:16.283 回答
2

好问题...

但是,Compiler 不会调用方法来匹配形式参数。如果可能,它只是尝试投射对象。

但是,当您使用“+”运算符时,编译器默认执行其参数(如果它们是对象)的 toString() 方法。

于 2012-07-30T08:37:19.953 回答
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.

于 2012-07-30T08:41:35.517 回答