Cristian Senchiu

Ranch Hand
+ Follow
since Feb 08, 2009
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Cristian Senchiu

Well ... Devaka was quicker and gave such a explanation that I have to quit (after writing half of my post ... )
But I still have a trump: generics unveiled

Mahalakshmi Chandru wrote:Cristian,
Thanks for clarifying the doubt. Its clear now . After i completed reading the wrapper classes topic and the autoboxing , its pretty much clear now. Im trying to understand the underlying behaviour of the classes by looking through the jdk installation.


You're welcome Mahalakshmi!

Ruben Soto wrote:You are absolutely right, Cristian. I missed the part that says "If only one of the operands is a String." So things make absolute sense now, thanks.

I hope you enjoyed your movie. I also saw a movie. It starred javac and had a lot of exciting exceptions. In the end everything compiled right.


Yes I did, thanks! I'm glad that yours had also a happy end.

Ruben Soto wrote:I think the main thing is that I don't see how there is a specific concatenation for String + String. I looked in the JLS (15.8.1) and I don't see a mention of a special case when both operands are Strings vs (for example) a String and a StringBuffer. Where did you find in the JLS this information?


Sorry for my late response. A movie was in the way.
Yes Ruben, my explanation was not the best I could give, and I think I understood which part was misleading:

... there's the specific concatenation for case String+String (so for compiler the String+<reference> is not the best choice anymore as it would be in case of any object, including StringBuffer for example).


So, JLS says

If only one operand expression is of type String, then string conversion is performed on the other operand to produce a string at run time.


That is:
- there's the case when one operand is not String. All objects are here (beside String objects) plus all primitives (as JLS says primitives are converted through their wrappers). So I have here always the case String+<reference> (unhappy naming of the case?)
- and there's the "specific" (unhappy usage of word specific?) case String+String
So in our case with String, the compiler goes in the case (generates instructions for) String+String and avoids String+<reference> case (for which would generate instruction if we would have another object, StringBuffer for example).

Ruben Soto wrote:

Cristian Senchiu wrote:Yes Ruben and Ankit, it was!
P.S.: I just reread my post and saw that I didn't write about the special case &amp;amp;quot;String&amp;amp;quot;, which is now easily explained through the efforts compiler makes to find the most specialized code.


Cristian, I am afraid I don't follow. How is String explained, when String and StringBuffer (for example) behave differently in the first case?

Good work, by the way!


Thanks Ruben.
The String case is that one case that throws already at lineX, where no other type of object throws. Remember? Was in our discussion at the very beginning.

That's explainable now because there's the specific concatenation for case String+String (so for compiler the String+<reference> is not the best choice anymore as it would be in case of any object, including StringBuffer for example).
Yes Ruben and Ankit, it was!
P.S.: I just reread my post and saw that I didn't write about the special case "String", which is now easily explained through the efforts compiler makes to find the most specialized code.

Mahalakshmi Chandru wrote:Cristian,
could you please elaborate what happens in the below 2 code snippets:Its kinda confusing


Hi Mahalakshmi,
the first code just creates the Integer object and sets its value. The second one is autoboxing and goes through the Integer pool. If it finds a cached one (must be between -128 and 127 ) it uses it, if not it creates a new one.
[EDIT,edit...]: Take a look in your jdk installation. You have there the sources for all classes and you can sneak a peek when you want to see how things are implemented.

Karl Krasnowsky wrote:
1) code on line 21 has a call Suits.SPADES.points and that can't work because the points member is private. Compile error #1.
...


Hi Karl,
you are right with one small change: the first error you report is at line 6 not 21 (see compiler's output).

Mahalakshmi Chandru wrote:Hi,
Please clarify whether both I and Is are same:


It depends, "the same" by means of what? If by means of "equals()" yes. If by means of "==" no.

Just a note: if we change the code to

Then they are the same through "equals" and "==", as boxing and valueOf both use the pool.

nagaraju uppala wrote:Thanks cristian
now my doubt is cleared. you mean at runtime also the generics will replaced with object type.am i right?


1.If are talking about the types:
The types will be erased to their bounds.
No bounds => erased to Object. If it would have been, for example, T extends BoxyTwisted1 => T would be erased to BoxyTwisted1.
2.If you are talking about the usage:
Yes and no... It is more complex, depending on what the compiler has to guarantee us ... As you can see when you read my previous post (right above your last post).
But this whole discussion is way beyond exam's objectives .... I presume.

Ankit Garg wrote:
This is the same code that the compiler generates for the println statement. But there is no exception at the println statement. May be this is because the println statement (or infact any string concatenation like at line no 14) is modified to StringBuilder code by the compiler after the generics code is erased...


Ruben Soto wrote:Good one, Ankit! Excellent test, which clears up some doubts.




Ankit, Ruben,
my fellow ranchers, you are going in the wrong direction...
Is not about the compiler "messing around", one time taking the generics into consideration and one time not. It's about the compiler finding the most specific method (JLS compiler-requirement).
Let's take those two lines of code which behave different and see what compiler must do for us:



#lineX
box.u is the second operand used with a "+" operator, in which the first operand is a String => we are in concatenation case => what rules do we have for concatenation of String with something that is an reference? => two rules: [if reference is null the rule is String+"null"][if reference is a non-null reference the rule is String+<result of calling toString() on the object that reference points to (if null is returned then "null" will be used)>]
That's all. There's no specific handling for specific types of object, thus no checkcast is needed.

#lineY
Here we use box.u as argument of a method. Compiler must look for the most specific method for our argument, finds one and chooses it.
But then it has to ensure that at runtime the object we give as argument is really of that type. So, in compiled code it inserts a checkcast instruction on that type, in our case checkcast java.lang.StringBuffer. Which of course throws at runtime as the instance on the heap is in fact a BoxyTwisted1.
If the String

So, the code at lineX is not the same code the compiler generates for lineY. There's one important difference: lineY makes that checkcast.

Thus lineY will fail for any type of object that has a specific StringBuilder.append(), including any implementation of CharSequence, java's or ours.
But it will not fail for other type of objects.

Let's restore my initial code (so much changed in all these posts ), clean it and add the two lines above plus a dummy implementation of CharSequence:

Pfui, this was a long one ...

[edit]:
This also explains why lineX throws when the type is a String

as there's the specific concatenation for case String+String and String+<reference> is not the best choice anymore.

Eric Pascarello wrote:for a second change the 5000 to 1000


True Eric, but sandeep asked for

sandeep kethe wrote:... which has to be reloaded for every five seconds

At the beginning, the title of the thread was misleading to me too ...
Hi nagaraju,
The two generics ( T and UU used in BoxTwisted) are unbounded. That means the compiler will erase both T and UU to java.lang.Object.
So the method

will be erased to something like this

Going further: now the cast is not even needed anymore, as we have Object cast to Object.

If we go again further (not needed for the SCJP exam, just for fun): in the compiled class, the associated instructions for this method would be something like this:


P.S.: explanation is based on the code I wrote in my first pot in this thread, that's why the "BoxTwisted" name ...
It's very simple to do such a function. I made an example for you:
Hi Trupti,

I mean in javascript, like this:

In exception handling, besides other actions, I do usually also a log on the server, with stacktrace and everything, as in java.
Like this I can look into the log file on client's server and see what happend, where, why ...