Never Use toString() for Behaviour
java.christmas
java.christmas
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.github.io/jvm/java/openjdk/biased-locking/20...
That said, it does seem like Microsoft has since moved away from overriding ToString for such things. In all honesty, Object.ToString was probably a mistake to begin with.
Any form of (semi-)automatic SomeObject -> String should be treated as a convenience for the developer to avoid getting a non-descriptive memory location reported.
Having the automatic toString isn't the problem, but maybe the name of the method is. It could be called "asDebugHelpRepresentation" or something more descriptive.
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.
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.
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.
Most Java developers I know consider rolling your own multi-threading scheme about as wise as rolling your own cryptography, and just pretend notify/notifyAll/wait don't even exist.
It's not that easy as I thought (see my sibling comment).
I am not too familiar with java, but should’t you call get() from optional to get Country from Optional<Country> and toString of Country will behave as expected.
You generally would not want to call '.get()' without an 'isPresent()' check because it will throw a NoSuchElementException if the Optional is empty. This is a foreseeable case, so most would like to handle it somewhat explicitly.
Today, it is idiomatic to use '.map' to transform it:
Optional<String> foo = optionalCountry.map(Country::getName);
You can also throw a domain-specific exception from that point: Optional<String> foo = optionalCountry
.map(Country::getName)
.orElseThrow(...);Serialization should require involve separate APIs.
I want to be able to design objects that have toString() and I want to be able to design objects that don't have toString().
The same goes for clone(), hash(), getPtr(), getEndian(), equals(), toBytes(), toJson(), encrypt(), delete(), isNumeric(), toXml(), serializationVersion() or compare().
Now I'm wondering... are there languages which formalize "implement with a throw" into some kind of explicit refusal to implement a method? Obviously there are method-sharing approaches other than inheritance, but I've never heard of "you must implement this, or explicitly choose not to".
Java doesn't have a language-level exception that's specifically for unusable methods, which can be a bit awkward. UnsupportedOperationException is the recommended answer, but it's relatively nonspecific as to why your operation wasn't supported. Apache's Commons extends that with NotImplementedException for cases where the call isn't definitionally impossible (e.g. adding to an unmodifiable map), but no implementation exists.
[0] https://docs.microsoft.com/en-us/visualstudio/debugger/using...
If they wanted to make it worse, they could make it so you could call %s on any object, and if it wasn't defined, it would "conveniently" fall back to %p instead.
Then someone could could write an article called "Never Use %s for Behaviour"
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)
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().
I think that's a bit harsh. It's an article explaining simply, but effectively why you should probably not use toString(). Just because something can be summed up in a sentence does not make it a waste of time.
In the end, I just think there are better channels for getting started with programming in a particular language then this site.