Reputation: 9512
I have a class
class Configuration {
// various stuff
@Override
public String toString() {
// assemble outString
return outString;
}
}
I also have another class
class Log {
public static void d(String format, Object... d) {
// print the format using d
}
}
The Log class works perfectly fine, I use it all the time. Now when I do this:
Configuration config = getConfiguration();
Log.d(config);
I get the compiler error The method d(String, Object...) in the type Log is not applicable for the arguments (Configuration)
. I can solve this:
Log.d("" + config); // solution 1
Log.d(config.toString()); // solution 2
My problem: How is this different? In the first solution, the compiler notices that it has to concatenate two Strings, but the second one is a Configuration. So Configuration#toString()
is called and everything is fine. In the compiler error case the compiler sees that a String is needed, but a Configuration is given. Basically the same problem.
How are these cases different and why is toString
not called?
Upvotes: 6
Views: 305
Reputation:
In one case you are passing an object argument to an operator which expects objects.
In the earlier case you are passing an object argument to a function which expects string.
Basically function/operator signature is different.
It is almost incidental [in the context of this question] that .tostring called when + is applied. It takes an object and does something.
For all you know, you might be passing in object when string is required by mistake. So it can't blindly do .tostring()
Upvotes: 2
Reputation: 4114
You are passing Configuration class object argument in case 1 but in the case 2 , you are passing string argument . so no error occures
.
Upvotes: 1
Reputation: 1132
Nice Question...
But, Compiler does not call a method to match formal parameters. it simply tries to cast the objects if possible.
But when you use the "+" operator the compiler executes the toString() method of its arguments (in case they are objects) by default.
Upvotes: 2
Reputation: 117569
One of the common use of toString()
, is print()
and println()
methods of PrintStream
, as in:
System.out.print(object);
System.out.println(object);
Basically, these two methods will call toString()
on the passed object. This is one of the Polymorphism's benefits.
Upvotes: 2
Reputation: 36977
The line
"" + config
gets translated to something like
StringBuilder sb = new StringBuilder("");
sb.append(config);
where the second line calls
StringBuilder.append(Object obj);
This method calls obj.toString()
to get the String representation of the object.
On the other hand, the first parameter of Log.d
must be a String, and Java doesn't automatically call toString()
to cast everything to a String in that case.
Upvotes: 3
Reputation: 346240
While designing the language, someone decided that when a programmer appends an arbitrary object to a string using the + operator, they definitely want a String
, so implicitly calling toString()
makes sense.
But if you call an arbitrary method that takes a String
with something else, that is simply a type error, exactly what all that static typing is supposed to prevent.
Upvotes: 11