It appears as if the replace(char, char) just returns the current string instance if the two characters are the same. Since the string instance you call replace() on comes from a string literal, it will be the same instance as the string literal you compare it to.
The replace(CharSequence, CharSequence) variant appears to return a new string instance, even if the method arguments are equal to each other. A new string instance will never be the same instance as a string literal.
Honestly, I really don't understand why exams include stupid questions like this. It tests absolutely nothing worth knowing.
The only real lesson here is that you must never use == when comparing strings. Always use equals().
Stephan van Hulst wrote:Honestly, I really don't understand why exams include stupid questions like this. It tests absolutely nothing worth knowing.
Stuff like that is precisely why I never bothered to sit for certification. Too much emphasis on things that would either cause me to be jailed for assault if someone inflicted them on me in the Real World and stuff that's so obscure that I'd have to look it up and find out what the latest rules were should I actually need it - And I'm thinking especially - but not only - of the Java assertion mechanisms.
The character versus character optimization is all well and good, but I wouldn't assume that it's universally true unless the Java specification explicitly says so. It's one of those things that a language (in this case, class) provider has wide discretion on how they implement.
As to the second case, if memory serves, the first argument is a regex and therefore it would be much more overhead to A) ensure that the first argument was a true string literal and nothing more and B) to search for that specific case as opposed to simply running the internal regex machine.
Stephan van Hulst wrote:The only real lesson here is that you must never use == when comparing strings. Always use equals().
Chisel it in stone above your doorway!
Sources may include data from the Fakebook Research Foundation with support from Gargle University
The behavior of String#replace(char, char) is of course not specified in the Java language specification. It is, however, specified by the String API. Mostly because it was written as part of JDK 1.0 by someone who evidently didn't know any better, over-specifying the behavior of the method. A few other methods put the same sort of behavior in their documentation - most do not. In particular, String#replace(CharSequence, CharSequence) does not say anything about whether it creates a new String in all cases. So, the behavior of this code is technically unspecified, and could change under a different JDK.
Even if it were specified, it would still make a very poor exam question. That level of detail in API of each method is not useful to memorize or worry about. The real exam did not have anything like this in its question when I took it many moons ago - I highly doubt they do now, either. Unfortunately, this sort of thing does show up in various lower-quality practice exams, causing a lot of pointless worrying.
Tim Holloway wrote:As to the second case, if memory serves, the first argument is a regex and therefore it would be much more overhead to A) ensure that the first argument was a true string literal and nothing more and B) to search for that specific case as opposed to simply running the internal regex machine.
No, String#replace(CharSequence, CharSequence) actually treats its first argument as a literal, not a regex. Which is quite unfortunate - that's not apparent at all from the name. The only (weak) excuse is that they were matching the behavior of the pre-existing replace(char, char) method, which also treats its first argument as a literal. So, all replace() methods treat the first arg as literal, and all replaceAll() or replaceFirst() methods treat the first arg as a regex.