Jesse Silverman

Ranch Hand
+ Follow
since Oct 25, 2020
Been programming "since forever" but Java was always a second (or third) language.  It's moving to the front seat.  I'm mostly harmless.
New York
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Jesse Silverman

Paul C:

Thanks for your post, too!  I followed your link and I now see that smart people might think that .intern() can help them, but that it is very unlikely to be the right way to get what they want, even if there is a legitimate reason to not want ten million copies of large strings to be bloating their heaps.  It cures my "but, but...." reaction to the blanket advice to pretty much forget that .intern() exists except when taking or writing real or mock exams.
Hi Paul A.:

You get what I was driving at, and why I provided an example after that was free of both + and .concat(), despite all the original confused certification seekers being sure that .concat() was to blame (which at first had me thinking that too).

I believe that the +/.concat() free examples I showed demonstrated that unlike in the old days, where the SCP was built up at load/init time in PermGen, 100% of all String objects (at least local ones, tho I suspect the others too) are just in the heap, with whatever data structure holding the references to the constants and other .intern()'d strings on the heap being built up only as the first line of code referencing each of them executes.

So it is now possible, (just recently since Java 7!!) to .intern() something you input from the external world or build yourself (with or without .concat() or +)  and to have THAT specific value be pulled from the SCP on even the very first line containing it (as the value of a constant expression) is executed during code execution.

You realize how picky I am about details, because I've spent decades fixing code of other people who decided "my code is just fine, but it isn't working, so go fix it".  In this case, while the bigger problem is that people are still innocently reading user-level tutorial materials causing them to think the SCP is separate from the heap in PermGen/method area, even those who do not labor against this misconception "know" that all compile time constant string expressions are placed into the SCP first, before any of the code in the methods of their class is executing.  I believe that the demo programs conclusively demonstrate that is no longer the case.

I was calling it an edge case, because "normally" you are very likely going to usually see a "Compile Time Expression" either by itself or as part of the first reference to any String object, e.g. new String("Compile Time Constant");
There are tutorial examples that demonstrate contrary behavior, and mock exam questions with contradictory "Correct" answers that are still floating around out there and being accessed that demonstrate the Java 6 behavior of what I am still calling this rare edge case, and confused students who are mis-concluding that the behavior of .concat() has changed.

There are certainly other changes that invalidate old tutorial and old mock test materials, such as effectively final, auto-boxing/unboxing, covariant return types, etc. -- but these all seem to have relatively very high awareness that they are no longer applicable to current Java.

You operate very close to what I consider to be the second most important cache of material second only to the actual pool of actual real Oracle exam questions, so I am super-happy to see you on this thread.

I don't disagree about counting.  It is in the class of "things just for the cert exam" along with i = i++; and predicting the behavior of complex nested loops with labelled continue and breaks that violate every rule of clear safe coding.  I would also throw in the complex expressions that rely on having the whole table of precedence for all operators memorized to predict, like we are war-rationing parenthesis.  Probably also many of the almost-pointless uses of multiply nested inner classes, having local, this and superclass data members shadowing and hiding each other, variables named var, using reference variables to access static classes etc. which would hopefully all fail code review and never get checked into code...

Of course, I am Desperately Seeking Certification, so all those things matter at least until then.

Maybe the irony is that the core thing they want you to know is "don't use == for values equality of wrapper classes and string" which I have seen in Production Commercial code too many times to count.
All of the places, tutorial or mock question that I've seen talking about intern() and asking you to count objects by looking at the result of == comparisons seem to exclusively use local variables.

I didn't try any experiments with instance variables, class variables, static initializers, etc. because that definitely seemed out of certification scope.

I think the point I was making was that tutorials that are not of generally poor quality still give misleading or wrong advice in this area.  Before gravitating to JavaRanch/CodeRanch, I got burned a number of times by looking at poorly vetted/curated content.  Even some of the better stuff has been kept online for ages with no updates.

I think that the consensus so far (of two) is that this is way out of scope for the 819, tho?
I already know the authors consider any use of .intern() in code to be bad style as quoted above.

When first learning about .intern() it sounded great to me, because I have seen so many terabytes of dumps of huge native code images filled with an insane number of repetitions of the same relatively small number of String objects, like 25% of the whole memory or maybe more...but the S&B book (J&S?) has warned me away from that attractive nuisance.  I guess the hazard of winding up with a whole bunch of String objects you thought you were going to need many of for a long time bloating the SCP means it just isn't worth the risk.
Thanks for your reply, Mike!!

I hope that everyone writing mock exam questions, and even more so, real ones, going forward reads your reply.

I would still maintain that some very commonly referenced written and video tutorial sources relate no-longer-accurate details on the behavior of the SCP, especially on when exactly it is built, and I encountered a good number of individuals trying to prepare for the exam scratching their heads over this, none of whom ultimately figured out what was going on.  I've seen some newer information sources that say "Well, it moved from method area to heap but everything else is still the same."

I posted the link to this thread in places where others confused by stale exam prep material voiced their confusion and uncertainty.

I certainly agree there are a million other things more useful to learn for the 819, I'll get back to those now!

Thanks again!
I am going to quote Scott and Jeanne from the section of their book named "The String Pool", Chapter 5, Page 180:

When you write programs, you wouldn't want to create a String of a String or use the intern() method.  For the exam, you need to know that both are allowed and how they behave.

They then provide a neat NOTE:
Remember never to use intern() or == to compare String objects in your code.  The only time you should have to deal with these is on the exam.

I'd be terribly embarrassed that I even started the thread except it is all about intern() semantics and is on the Programmer Certification (OCPJP) thread.
Certification seekers think this issue is in scope for the exam, which it may or may not be, and are very confused about how the code in these examples works due to having absorbed outdated material that abounds all over the internet in every form (if my analysis of what is going on is actually correct).
I felt bad that poor concat() was being blamed for this by hapless certification-seekers and befuddled video watchers.
This completely and totally exonerates concat() proving it just got blamed because it is so frequently used on mock exam questions:

Wait.  Now I am questioning the following line from the JLS itself!

Strings computed by concatenation at run time are newly created and therefore distinct.

"My name is Elmer J. Greenhorn.  I own a mansion and a yacht!"

I guess this is still true, with the edge case exception that if the value of one of these concatenations has intern() called on it before the first line referencing the compile time constant , the SCP will use that intern()'d value as the reference value in the SCP for the rest of the program.  Further calls to .concat() will all produce distinct new values taking up additional heap space for each one.
That this also yields the same runtime behavior with modern JVM instances may further underscore my point, as the String in question is marked final and therefore eligible to be treated as a Compile Time Constant.  I'm not sure anymore.  But it behaves the same;

I feel like I know a lot of true statements that have remained true about the "String Literal Pool" or the "String Constant Pool", as I see it variously called in different posts and articles, even within this forum.  If I understand correctly, the behavior has zero dependence on what you compile with, and solely on which JVM is running the code, what's more, I suspect that this all changed ten years ago and is only confusing people because there is so much stale information about SCP out there in old tutorials and archived discussions and old mock exam questions.

My current belief is that the following statements from the certainly great-at-the-time but possibly no longer quite true tutorial on this site may have become inoperative:

When a .java file is compiled into a .class file, any String literals are noted in a special way, just as all constants are. When a class is loaded (note that loading happens prior to initialization), the JVM goes through the code for the class and looks for String literals. When it finds one, it checks to see if an equivalent String is already referenced from the heap. If not, it creates a String instance on the heap and stores a reference to that object in the constant table. Once a reference is made to that String object, any references to that String literal throughout your program are simply replaced with the reference to the object referenced from the String Literal Pool.

A downstream conclusion from this fundamental explication that I believe is no longer applicable now is:
Strings created at run-time will always be distinct from those created from String Literals.

It is my current belief that the String Constant Pool seems to now be built up during code execution, so that if a String Literal that the JVM is considering adding or looking up in the pool has already been added to the heap and then the SCP by executing user code, it will choose that very one as the reference to add to the String Literal Pool.  In the old days, as this was done before a single line of user code executed, at class loading time, that would never ever happen.

The reason this matters so much (or at all) is that the simple downstream conclusion mentioned both in that article and many other places that exam-preparers are reading is no longer operative.  Instead, it instead now depends on whether the code creating the string that is only created at runtime executes before the line that references the string constant!

I never loved these questions about "how many String objects get created?  Where?" which I see from some sources are indicated to be much more common in preparatory materials and mock exams than on real exams.

Referenced "Was-Great-At-The-Time-But-Confusing-To-New-Exam-Takers-Now" article from this site:
I can't resist commenting on my own post.  By 2020 standards this isn't too bad.

I believe that what is going on is that the entire notion that the Internet collectively has echoing due to tons of outdated material being more readily accessible than current stuff, which is to say that SCP and heap entries are disjoint and distinct, is just no longer operative.  Since the time that the SCP moved out of PermGen into the heap (just in time for the PermGen to be wiped out in the next major release)...the notion that you can figure out whether a particular String value came from the SCP or not by just calling intern() on it and seeing if you get a new value back or not doesn't work anymore.

String s3 = s2.intern(); // just adds a reference to the already existing s2 on the heap to some SCP data structure, and returns the same value, so that s3 == s2 ??

For reference, the people that I saw standing around scratching their heads and fretting were thinking that .concat() behavior changed, because they had previously been so conditioned to think that SCP references were inherently disjoint from new String() references.

I saw a really, really old comment from Bert that addressed what was in scope very long ago, which was more authoritative than if President Clinton himself had said so.  But a bit stale.
First I want to just mention defensively that I have debugged hundreds of programs I didn't even have source for by reverse-engineering native code, both at work and for "fun" and occasionally even fixed bugs and re-assembled them (not at work!).

So I think the focus here needs to remain on whether or not this mess is in scope for the 819.

I also want to comment that this is exacerbated by the fact that a lot of people are looking at old preparation materials for earlier SCJP exams, and there have been changes in Java itself in the area.

I believe the standard references on this site don't reflect modern SCP details in this matter, if they do I am legitimately confused.

The code with puzzling behavior which I wish to know if it is in scope or not for the 819 is:

The output is "true", "true".

I saw other certification-seekers commenting on "Why am I getting different behavior???" in an older video that I am sure was true at some point but I think is now out-of-date.
Trying to explain the difference of behavior led me to:

After reading that, I came to the conclusion "These sad Anoraks should really get a life!!  Nobody needs to know this except the team working on the String code!!"
Then I realized that maybe I need to memorize something about how the Oracle 11 OpenJDK implementation works in this regard in order to consider myself fully prepared for the Spanish Inquisition --- errr, 819 exam.  (I've been confusing the two a lot lately)...

Is why this outputs true/true in scope for the 819?
If so, and, probably, if we say it isn't, why does it do that?  It seems to go against a whole bunch of stuff I'd read about SCP behavior, only some of which I had believed to be outdated.

Campbell -- I would argue against that point, in that in NYC English, which has been popularized to a fair extent by movies, songs and tv shows around the world, but whatever, speaking as a very-long-term-native...

there are phrases such as dumb-ass, broke-ass, drunk-ass, lying-ass and cheating-ass which definitely have always been taken by myself to by referring to keisters, posteriors, rumps or hindquarters.

It is less important to Certification than strikethru availability, but something "normal" people would actually be interested in.

Apart from a possible very long-term etymological connection, not connected to the horse's cousin, I believe.
Grumpy since I only got 72% on the first try at the Chapter Review Questions, I had to find some complaint:
[Question 23, Online Test Bank]
"Which annotation can cancel out a warming on a method using the @Deprecated API at compile time?"

I do get a bit warmer when I see any warmings coming out of my compiles, but we probably meant the word to be warning.

All of the errors were on my own...fair enough it was just usual trickiness and a desire to go quickly that did me in...

Oh yeah, both books refer to an "Online Text Bank" in the introduction rather than an "Online Test Bank".
Since they also include the lovely flashcards and helpful glossary, that might be a more appropriate name for the Bank, but elsewhere we seem to exclusively refer to it as a "Test Bank".