• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Rob Spoor
  • Henry Wong
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
Bartenders:
  • Frits Walraven
  • Himai Minh
  • Jj Roberts

Sybex - Chapter 5 - Page 208 - Summary - Paragraph 3

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey guys,

The third paragraph states: "Calling == on String objects will check whether they point to the same object in the pool."

This is correct for string compile-time constants, eg. literals, and interned Strings.

This is incorrect for all String objects since the POOL is NOT used for ALL String objects.

Suggested edit: "Calling == on literal or interned String objects will check whether they point to the same object in the pool. "

Thanks,

Bassam

 
Marshal
Posts: 72407
315
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you are  correct. The == operator tests whether two references point to the same object. Even if those objects aren't in the String pool.
 
Ranch Foreman
Posts: 325
8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm doing a lot of cross-language studying these days so I am on high alert for terminology.

As Campbell points out, the operands to == are references, not objects (this isn't C++), so we can never touch the objects themselves directly, tho the syntax for string literals muddies that.

If we wanted to be really precise here, we could say:
"Calling == on references to String objects will check whether they point to the same object in the pool."
At the real-life moment that we have two string references that we might want to compare for being references to the same object, at some line of code somewhere we likely don't know where they came from.

If they both came from new String("Whatever") it will still check whether or not they point to the same Object.
It happens in that case that they never will unless someone assigned one reference to another somewhere, or passed the same reference twice to a method, but it is always valid to ask.

If you slouch about in dynamic languages, you will come to appreciate that:

Integer J = 5;
String s = "Five";
if (J == s) { ... }

will not even compile in Java.
It is illegal to ask if the references are to the same Object, the compiler knows the answer already: "Nope!"

The bottom line is that as written in the book, the line is true.
Your line is too precise, because if somewhere in the program before our test got called someone said:
       String s1 = new String("Tricky!");
       String s2 = s1;
       if (s1 == s2) System.out.println("The references are to the same String object!");

That would tell us they are the same, but your re-word suggests it would not.

So there are only a few ways we will get true out of that.
Both are the same literal.
Both came from a call to .intern() on the same String value at some point.
One came from a literal and the other one came from a call to .intern() on the same value.
Both happen to be referencing the same normal plain old regular string sitting on the heap.

This gets complicated fast, the original line is the only easy sentence that is true all the time.

The more important take-home is "Don't use == to compare strings for equality.  Learn when it will return true to get a good score on the OCJP and forget about it later."

I say this as someone who paid way too much attention to some wacky corner cases that people helpfully pointed out were beyond the scope of the test.
The fact that the pool used to be distinct from the heap and no longer is anymore is just one of them.

For people working in multiple different languages, I would prefer that the words "references to" be in there, however, when you are in Java all the time, everything (except the 8 primitives) is a reference, so it is perceived to be superfluous.
 
Bassam Gemayel
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Campbell,

We agree.

@Jesse,

The main discussion here is that readers understand that NOT ALL String objects are stored in the String Constant Pool (aka, pool).

Only compile-time constants Strings and Strings interned using the intern() method, are stored in the pool.

The rest of the String objects are stored somewhere else on the heap.

Thank you, both,

Bassam

 
Campbell Ritchie
Marshal
Posts: 72407
315
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:. . . will not even compile in Java.
It is illegal to ask if the references are to the same Object, the compiler knows the answer already: "Nope!" . . .

At the risk of Tim Holloway going on about people who avidly read the Java┬« Language Specification (=JLS), the compiler “knows” that the == test cannot evaluate to true because the two variables are of different types. Hence the compile time error. The compiler only “follows” the value of a variable when that variable counts as a constant variable.

Your line is too precise . . .

I think you have miusnderstood BG's point, which he explains himself.

"Don't use == to compare strings for equality.  Learn when it will return true to get a good score on the OCJP and forget about it later."

Agree: there are several circumstances where it is all right to use == :-
  • 1: Equality with primitives.
  • 2: Equality with null.
  • 3: Equality with an enum constant.
  • 4: When writing an equals() method.
  • 5: In a cert exam or cert exam revision.
  • 6: When you simply want to try something out to see what happens if....
  • BG is acting under No 5  or even No 6.

    . . .the words "references to" be in there . . . everything (except the 8 primitives) is a reference, so it is perceived to be superfluous.

    Quite right. People get confused when they see...and they think that x is an object rather than a reference. Remember that with escape analysis, that x might not be created on the heap at all.
     
    Bassam Gemayel
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    @Jesse,

    I would use "correct" instead of "precise" when describing an assertion.

    "Precise" begs the question of how much precision is requested.

    "Correct" is an absolute and does not have varying degrees of intensity or grade.

    Thanks again,

    Bassam
     
    Jesse Silverman
    Ranch Foreman
    Posts: 325
    8
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I see precisely what you are saying now.

    It is correct to say that only the things you have mentioned would be in the String Constant Pool.

    The only time you would care "in real life" outside of an exam would be if you are considering strings for possible .intern() calls, which is generally not recommended, it seems.

    For the exam, knowing that == compares two objects (of appropriate type) anywhere on the heap to see if they are the same object is important.
    There is a lot of old material out there that talks about the SCP being distinct from the heap, which used to be true before various re-factorings some time ago.

     
    Jesse Silverman
    Ranch Foreman
    Posts: 325
    8
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    In terms of the sentence in the summary on page 208, I would change it to:
    'Calling == on String references will check whether they point to the same object'

    I was thinking the sentence was in a part of the chapter explicitly about the SCP, but in that end-of-chapter roundup the sentence should just talk about the general case.

    Interestingly, in terms of whether we explicitly use the word 'references' or 'objects' are four sentences from that area:
    'Calling == on String objects will check whether they point to the same object' (I would have written references instead of the first word 'objects')
    'Calling == on StringBuilder references will check whether they point to the same StringBuilder object' (that is exactly what I would write here)
    'Calling equals() on String objects will check whether the sequence of characters is the same'
    'Calling equals() on StringBuilder objects will check whether they are pointing to the same object rather than looking at the values inside.'

    In this context, I think they should just write the shorter sentence I suggested.
    Why did they write objects in the first of those lines and references in the second?  The only guess I would have is because one of the sides could be a string literal in the source code.
    It still functions as a reference to an object somewhere in the heap, so I don't see why that would change the wording.

    One weird thing to remember about StringBuilder later because it might bite one due to its counter-intuitiveness (from the docs):
    StringBuilder implements Comparable but does not override equals. Thus, the natural ordering of StringBuilder is inconsistent with equals. Care should be exercised if StringBuilder objects are used as keys in a SortedMap or elements in a SortedSet. See Comparable, SortedMap, or SortedSet for more information.

    Where they say 'Care should be exercised' the safe thing to say is "Don't do this, it is an accident waiting to happen!" but I am not in charge of the docs.
     
    Campbell Ritchie
    Marshal
    Posts: 72407
    315
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Nor did you have the bright idea of making a class Comparable when it doesn't override equals().
     
    Bassam Gemayel
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Jesse Silverman wrote:
    In terms of the sentence in the summary on page 208, I would change it to:
    'Calling == on String references will check whether they point to the same object'



    That would be correct but redundant. You can remove "String" and the statement would remain valid.

    Jesse (edited) wrote:
    'Calling == on (compatible type) references will check whether they point to the same object'



    My intent was to add an informational value and underline the distinction between pooled and non-pooled strings.

    Keep it up,

    Bassam
     
    Jesse Silverman
    Ranch Foreman
    Posts: 325
    8
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    It is clear everyone on this thread has the required information about String equality and identity and when the String Constant Pool gets used.

    Your point is valid because there are many extant presentations that make it sound like all Strings get stored in the SCP, which is wrong, and always has been.

    I don't think a reading of this book in particular could leave one with that misconception, which I had myself at one point due to sloppy tutorial materials.

    They even make it clear that while it seems using .intern() in real code could be helpful, that is rarely the case in practice.
    There are other threads on this site that go into that in more detail.

    In the context of the general summary at the end of the chapter, I'd probably write the shorter sentence I suggested.

    The biggest problem that everyone should want to avoid including the exam writers at Oracle should be "Don't use == to compare String types or StringBuilder types for equality".

    When I considered myself a total Java novice, I would see people (for whom Java was supposed to be a first language) doing that in production code -- the reference count of that should go to zero.

    So, cool.
     
    Paper jam tastes about as you would expect. Try some on this tiny ad:
    SKIP - a book about connecting industrious people with elderly land owners
    https://coderanch.com/t/skip-book
    reply
      Bookmark Topic Watch Topic
    • New Topic