Scott Selikoff wrote:The reason toString() is called is that the closest matching overloaded version of println() is the version that takes an object, aka System.out.println(Object). If you look at the source, this method calls String.valueOf(Object), which then calls object.toString(). Since the Counter class overwrites this method, this version is used.
Campbell Ritchie wrote:If there were to be any problems like that, they would manifest themselves at compile time and the program wouldn't start. I presume you can tell us what poor design features that code shows.
Stephan van Hulst wrote:Why did you think it would throw an exception?
Stephan van Hulst wrote:Every time you call sb.toString(), it creates a new String instance. The reason for this is easy to understand: The string builder doesn't keep a reference to the previous string object it created, so it can't return the same string object when you call toString() a second time.
Stephan van Hulst wrote:The contents don't matter to the == operator. The == operator performs reference equality. If s1 == s2 returns true, it simply means that s1 refers to the same object that s2 does. So the question boils down to: Why does the string literal "OCAJP" yield the same string instance that "OCAJP" + "" does?
The answer is that the expression "OCAJP" + "" is a compile time constant expression. That means that the compiler can evaluate the expression during compilation and replace it with its final value, which is "OCAJP". When the application starts, all string constants that have the same value will all be represented by the same String instance.
Campbell Ritchie wrote:The comment is a bit mild; that code isn't “redundant”, but it hides a logic error.
Dave Tolls wrote:. . . That comment explains . . .