brimborium
brimborium

Reputation: 9512

toString: When is it used?

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

Answers (6)

user256717
user256717

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

Mohammod Hossain
Mohammod Hossain

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

Byter
Byter

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

Eng.Fouad
Eng.Fouad

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

Erich Kitzmueller
Erich Kitzmueller

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

Michael Borgwardt
Michael Borgwardt

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

Related Questions