That suggests that a temporary String object is created representing the number, and then it gets concatenated to the string on the left of the + operator.
[OCP 21 book] | [OCP 17 book] | [OCP 11 book] | [OCA 8 book] [OCP 8 book] [Practice tests book] [Blog] [JavaRanch FAQ] [How To Ask Questions] [Book Promos]
Other Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, TOGAF part 1 and part 2
This one is more interesting. The butecode shows that Java is smart enough to use a StringBuilder.
Raul Saavedra wrote:So there was indeed an intermediate StringBuilder object created there. Which suggests the right answer, as in Roel's analysis, ought to be 2000 and not 1000
Raul Saavedra wrote:And why would it have created it for your second example then?
Raul Saavedra wrote:Maybe because your second example has String and int variables, as in the book question by the way, while the first example has only literals?
Raul Saavedra wrote:Or maybe because the second example has more than one "+" operator??? Why use an auxiliary StringBuilder in one case and not in the other?
[OCP 21 book] | [OCP 17 book] | [OCP 11 book] | [OCA 8 book] [OCP 8 book] [Practice tests book] [Blog] [JavaRanch FAQ] [How To Ask Questions] [Book Promos]
Other Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, TOGAF part 1 and part 2
Raul Saavedra wrote:Even with what you said ("I think the authors mean this logically rather than on the implementation level") I would still point out, an apparent inconsistency still stands in the book. Answer to question 5.9 = 1000 being correct means the statement near location 5025 is rather misleading, and it truly doesn´t always apply, as shown by your own bytecodes. Precisely the simpler case (String s = "" + i), as in the self-test question, is the exception, but it was never explained that there was such an exception. So I would still suggest that this is something to be fixed/changed in the book: either question 5.9, or the explanations and choice of examples near location 5025.
Roel De Nijs wrote:For the certification exams (like OCAJP7 and OCPJP7) you do not need to know about this optimization performed by the Java compiler (nor the bytecode)!
Raul Saavedra wrote:
Roel De Nijs wrote:For the certification exams (like OCAJP7 and OCPJP7) you do not need to know about this optimization performed by the Java compiler (nor the bytecode)!
If that is the case, I tend to think the best errata addition would be to actually remove question #5.9. The correct answer for it depends on a compiler optimization, but that´s an exceptional case not covered at all by the instructional material in the book. In fact, it contradicts the explanations given in the book (not to mention, it is stuff not needed for the cert. exams after all, as you indicate.)
Raul Saavedra wrote:But chapter four, section "String Concatenation Operator" (location 5025) states: "The previous code can be read as “Add the values of b and c together, and then ****take the sum and convert it to a String*** and concatenate it with the String from variable a.”"
That suggests that a temporary String object is created representing the number, and then it gets concatenated to the string on the left of the + operator.
If the above is truly the case, then the answer to Self-test question 5.9 cannot be approximately 1000 but 2000, or in fact maybe 3000? (For example, if an Integer wrapper object is created, and then its .totring() method called to get the string to concatenate, then we have the Integer object, and the String resulting from its tostring() method, so two intermediate objects right there).
Raul Saavedra wrote:At least a small note along the lines of:
"Beware that besides the result String, in some cases an intermediate auxiliary object gets created (e.g. a StringBuilder) to process the concatenation more efficiently, but in some simple cases like the following (and then an example as in question 5.9 would follow) just the resulting String gets created, without the need for this extra auxiliary object or intermediate String objects."
Roel De Nijs wrote:and then a loop which creates 1000 new String instances (by concatenating " " with the loop counter) and append each one to sb. So that results in about 1000 objects in memory.
Jeanne Boyarsky wrote:I agree with the book that the answer is 1000. I looked at the bytecode to confirm. (You can see how I got the bytecode and what it actually is on my blog.) The gist is that there is only one String created from
Raul Saavedra wrote:Hope to have better explained where I see the point of this errata submission.
Roel De Nijs wrote:The statement in chapter 4 (location 5025) is indeed misleading/wrong as it implies the sum is first turned into a String before being concatenated to the other String (which would double the number of objects). So I would propose the following fix.
Currently: The previous code can be read as "Add the values of b and c together, and then take the sum and convert it to a String and concatenate it with the String from variable a."
Should be: The previous code can be read as "Add the values of b and c together, and then take the sum and concatenate it with the String from variable a."
Raul Saavedra wrote:Now I wonder if that little thing precisely can possibly make or break the deal about whether there are 1000 or 2000 GC elligible objects created in 5.9. Could you please check the bytecode using a string with a space and not an empty string?
Roel De Nijs wrote:That doesn't matter!
Raul Saavedra wrote:
Roel De Nijs wrote:That doesn't matter!
I'm not so sure, because see my own analysis and counting of objects.
Roel De Nijs wrote:True! But that's totally on another level. You don't want your compiler to act differently based on the content of your strings/objects you are using.
Raul Saavedra wrote:But if we use " " (or "_" or "abcd" or any other nonempty string as literal for that mater) as question 5.9 original states, there will be 2000 objects.
Roel De Nijs wrote:
Raul Saavedra wrote:But if we use " " (or "_" or "abcd" or any other nonempty string as literal for that mater) as question 5.9 original states, there will be 2000 objects.
Really curious to know which 2000 objects there will be in memory in question 5.9...
We have (watch the space in front of every integer): " 0", " 1", ..., " 999". So that gives me a 1000 objects. I can't think of any other 1000 objects being in memory when executing the code in question 5.9.
Raul Saavedra wrote:The ones you indicate: " 0", " 1", " 2"
And the intermediate string representation of ints (as suggested by ch 04) that get concatenated to " " in s = " " + i; Those would be "0", "1", "2"...
Roel De Nijs wrote:
Raul Saavedra wrote:The ones you indicate: " 0", " 1", " 2"
And the intermediate string representation of ints (as suggested by ch 04) that get concatenated to " " in s = " " + i; Those would be "0", "1", "2"...
Are you pulling my leg?
Raul Saavedra wrote:Notice that no new String object would be effectively created at runtime in the second for loop in this code. Because the expression "" + i; will always produce a String that is already in the string pool.
Raul Saavedra wrote:tell me if you agree with what objects were or were not in the string pool already, and which hang loose or not.
Roel De Nijs wrote:
Raul Saavedra wrote:tell me if you agree with what objects were or were not in the string pool already, and which hang loose or not.
Strings, Literally is a must-read for everyone who is preparing for OCAJP and/or OCPJP certification.
Raul Saavedra wrote:Ah that definitely helped a lot, Roel, thanks for the link! Did check it. Did not know about this intern method, and I was under the impression that strings with equal values even created at runtime would not be replicated (as if always this intern method had been called.) Which is why I wrote the previous (now misleading) illustrations the way I did. Now I know better, thanks again.
Raul Saavedra wrote:Who is that someone in this case that (in the fixed version of text in ch04) would "take the sum and concatenate it with the String from variable a" ?? Who exactly does that work if not an object?
Roel De Nijs wrote:
Raul Saavedra wrote:Who is that someone in this case that (in the fixed version of text in ch04) would "take the sum and concatenate it with the String from variable a" ?? Who exactly does that work if not an object?
I guess the same person/thing who adds 2 integers or multiplies a double with a long or invokes a method. The JVM!
Raul Saavedra wrote:I don´t see where´s the optimization in using a StringBuilder for a + (b + c), why didn´t just the same JVM which always does all that added the two integers on its own before the concatenation, saving one object creation (the StringBuilder) from the deal?
Roel De Nijs wrote:
Raul Saavedra wrote:I don´t see where´s the optimization in using a StringBuilder for a + (b + c), why didn´t just the same JVM which always does all that added the two integers on its own before the concatenation, saving one object creation (the StringBuilder) from the deal?
The JVM will still be the guy that invokes the necessary append methods after the compiler has optimized your code using the string concatenation operator. If the compiler doesn't do this optimization, you'll create (in any application) millions of temporary strings (a string is immutable as you know, so each concatenation is a new - probably auxiliary - string). These millions of temporary strings are using (wasting) your precious memory.
Raul Saavedra wrote:Somewhat that does not fully add up. What I kind of see is that if creating the StringBuilder would be suboptimal to use for just b, then it would also be suboptimal for (b+c). And on the other hand, if the creation of the StringBuilder is allegedly an optimization for (b+c), it should also be so for just b.
Roel De Nijs wrote:In the bytecode I posted a few posts back, I see both times a StringBuilder being created... And the code was of the format String s = a + b;
Raul Saavedra wrote:Ok but that would support the 2000 answer again, wouldn´t it?
Raul Saavedra wrote: And how is that compatible with Jeanne's finding for the simpler case, where only one String gets created, in principle no StringBuilder involved?
Roel De Nijs wrote:If you only concatenate compile time constants, no StringBuilder is required to concatenate
Jeanne Boyarsky wrote:Because the second example has more to concatenate so Java optimizes it.
Roel De Nijs wrote:I hope you now understand the compiler does a whole set of possible optimizations to make sure your code runs as performant as possible, both in time as in memory usage. And that it's almost impossible for a beginner (and even for an advanced developer with 10 years experience like me) to know all these optimizations.
Raul Saavedra wrote:Believe it or not I have more than 5 years of java experience myself and I´m SCJP 1.4
Raul Saavedra wrote:I haven´t worked with Java at all for the last 10 years, so I´m using the recertification and Java7 to brush up everything.
Raul Saavedra wrote:Given what you say about compiler optimizations not needed for the exam, I still tend to think question 5.9 ought to be out of the book. Just as easily the question could have used a String variable and not the " " literal to the left of the first plus, and from the book, even corrected with your suggestion, the answer would still seem to be 1000, but in that case it would be 2000. And there's no way a reader could understand why that would be the case unless the book mentions at least that simple optimization done by the compiler.
Raul Saavedra wrote:I somewhat find the emphasis in so many "The code fails to compile" questions in the Cert exam to be somewhat misdirected or even absurd. Because use-case wise, when a tricky code fails to compile the developer would know it immediately and exactly why when running the compiler. In that sense, it is to some extent not so critical whether by just looking at tricky code we can tell if code fails to compile. On-the-job wise, and for efficient coding, I find it for example much more important to know about this particular compiler optimization we have been talking about here.
Roel De Nijs wrote:
Raul Saavedra wrote:But if that was the case, the book would have mentioned about 2000 as a correct answer and would have explained why it's 2000 and not 1000...
Raul Saavedra wrote:What I mean, your proposed errata fix at least removes the inconsistency in the book between instruction in chapter 4 and question 5.9. But to me presenting that question given what was taught, even with the proposed fix, is in itself questionable. What was taught was insufficient, somewhat misleading (and I keep repeating this word.)
Wanna see my flashlight? How about this tiny ad?
Smokeless wood heat with a rocket mass heater
https://woodheat.net
|