Live data from Hacker News

Never Use toString() for Behaviour

java.christmas

31–40 of 51 posts

Re: Never Use toString() for Behaviour

#31
post #5

>If left unoverridden, it only yields a description of it’s class and location in memory It contains the hashCode(), not the memory location. The default implementation of hashCode could use a memory location to generate the hash, however that isn't the case in all implementations. OpenJDK seems to have used an RNG by default in the past and currently derives a value from the thread state[1] [1] https://srvaroa.githu…

for most implementations it would not be possible to use the location in memory because most java garbage collectors will move stuff around in memory. they could use the location initially and cache it afterwards but this would seem tricky to do without breaking the hash code contract.

I think the code also has the option to read and store the address. However I also think it would have other problems. Heaps with less than 4GB size would put a limit on possible hash code values and object alignment requirements would make it even worse, so you never get use out of the full 32 bit hashCode. Then you have generational GCs and if I understand those correctly you could end up with a lot of objects that started out at the same address and if you call hashCode on them before they are moved to a long lived generation you almost guarantee a large amount of hash collisions down the line.

Re: Never Use toString() for Behaviour

#32
post #30

Earlier quoted context omitted.

The typical usage for StringBuilder tends to make it pretty obvious you're using a StringBuilder and everybody expects you will convert to a string at the end. Usually StringBuilders are short lived and all the calls and the declaration are close to each other.

Ok, but then the rule is not to use toString() for behavior unless it "makes sense" to do so, which is not a rule at all.

I think that misses my point. It's an established pattern recognizable to anyone who has read or written a lot of code. And locality of use and declaration is high. The danger of it being mixed up with another type in a refactor in faraway code is low.

Whereas in the general case, where code can be sparse and types can be more freely altered, you could very easily change the type of something and not realize that a ToString() call on that type lurks somewhere else in the code base.

Re: Never Use toString() for Behaviour

#33
post #27

Java's eccentric uncle Objective-C called this method "description" instead of "toString". That was a better name IMO because it avoids the suggestion that it's some kind of canonical string representation.

Yeah, it really would be helpful if the method name made that clear.

The language documentation does make it clear what toString() is for. And it's convenient to be able to (for example) stick objects and strings together with the "+" operator and have conversions automatically happen.

But (understandably) not everyone reads the language documentation cover to cover before they start writing Java code, so you can't count on that making it obvious.

Re: Never Use toString() for Behaviour

#34
post #7
post #3

That was a complete waste of time. To sum it up: don't rely on the format of a generic toString() method. Prefer country.getName() over country.toString(), even if toString() returns getName().

It's cool to read, but yeah, it's like reading Beginner's Java, lesson 3.

Unlikely. Beginner's Java, lesson 3 is the reason people are using toString() erroneously in the first place.

Re: Never Use toString() for Behaviour

#35
post #13

Never use a language that puts a toString() implementation on every object regardless of whether or not that object implements toString()

Hah, such hate.

Lemme quote Goetz & Steele:

"Standard methods like toString and equals should not be forced on value classes, but should be customizable." (http://cr.openjdk.java.net/~jrose/values/values-0.html)

Re: Never Use toString() for Behaviour

#36

We use lombok, and the toString annotation is immensely helpful for logging and avoiding this type of thing.

How does Lombok help to avoid this?

Lomboks annotation @ToString will automatically generate the typical overridden toString() method based on the fields.

Re: Never Use toString() for Behaviour

#37
post #27

Java's eccentric uncle Objective-C called this method "description" instead of "toString". That was a better name IMO because it avoids the suggestion that it's some kind of canonical string representation.

Ah, Objective-C: Combining the blazing-fast speed of Smalltalk with the famous memory-safety of C.

Re: Never Use toString() for Behaviour

#38
post #37
post #27

Java's eccentric uncle Objective-C called this method "description" instead of "toString". That was a better name IMO because it avoids the suggestion that it's some kind of canonical string representation.

Ah, Objective-C: Combining the blazing-fast speed of Smalltalk with the famous memory-safety of C.

[deleted]

Re: Never Use toString() for Behaviour

#39
post #27

Java's eccentric uncle Objective-C called this method "description" instead of "toString". That was a better name IMO because it avoids the suggestion that it's some kind of canonical string representation.

Yeah, it really would be helpful if the method name made that clear. The language documentation does make it clear what toString() is for. And it's convenient to be able to (for example) stick objects and strings together with the "+" operator and have conversions automatically happen. But (understandably) not everyone reads the language documentation cover to cover before they start writing Java code, so you can't c…

java.lang.Object has a few methods though. At least those should be known when one starts writing productive code. Otherwise one produces even worse bugs than relying on toString behavior (equals and hashCode, god forbid).

Cover to cover would mean understanding the memory model and maybe garbage collection. That's too far certainly but a few basics would do no harm. toString is surely one of them.

Re: Never Use toString() for Behaviour

#40

Earlier quoted context omitted.

How does Lombok help to avoid this?

Lomboks annotation @ToString will automatically generate the typical overridden toString() method based on the fields.

Even Object.toString could do this using reflection. If you're worried about the performance, override it. I never understood why this is not the case (doesn't Haskell do something similar?).
Post reply on HN