| Author |
Box or Unbox
|
Sahil Kapoor
Ranch Hand
Joined: Sep 12, 2009
Posts: 316
|
|
Consider the following switch statement.
While JVM is doing its processing, what of the following two it would do ?
1) It would unbox switch expression ie new Integer(4) and compares it with int w.
2) It would Box w and then compares with the switch expression.
Thanks !!!
|
SCJP 6.0 96%
(Connecting the Dots ....)
|
 |
Ireneusz Kordal
Ranch Hand
Joined: Jun 21, 2008
Posts: 423
|
|
Sahil Kapoor wrote:
1) It would unbox switch expression ie new Integer(4) and compares it with int w.
2) It would Box w and then compares with the switch expression.
Hi
1 is true - it would unbox new Integer(4)
Look here in the specification:
http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.11
When the switch statement is executed, first the Expression is evaluated. If the Expression evaluates to null, a NullPointerException is thrown and the entire switch statement completes abruptly for that reason. Otherwise, if the result is of a reference type, it is subject to unboxing conversion (ยง5.1.8). If evaluation of the Expression ....
|
 |
Sahil Kapoor
Ranch Hand
Joined: Sep 12, 2009
Posts: 316
|
|
Thanks a lot sir !!!
But in accordance with docs , the following two usages of switch statement must be same , but indeed they are different , second program will show compile time error.
Program 1 :-
This program would compile fine. No problem !!!
Program 2:- This is essentially same the above code according to docs , but shows compile time error.
But but but, if the case would be like , case constants are boxed , ie option 2, then in accordance to it, the above two codes behaviour could be reasoned.
Thanks !!!
|
 |
dipayan chatterjee
Ranch Hand
Joined: Oct 03, 2007
Posts: 47
|
|
Hi all
Sahil has put a good question the program 2 specified by him certainly looks like a benign java code that should run fine but it is throwing a compile time error
switchlochaTst.java:8: incompatible types
found : char
required: java.lang.Integer
case 's': break;
^
1 error
I am quite perplexed by this error as according to JLS the wrapper object is unboxed to int and as 's' being a character it is implicitly cast to int so everything should work fine. So ranchers need your help in understanding the reason for the error
Thanks in advance
|
 |
Lalit Mehra
Ranch Hand
Joined: Jun 08, 2010
Posts: 369
|
|
i think
's' needs to be explicitly declared as an int or type Integer.
it is so because in the second switch statement we are not providing a constant as an expression but a reference to an Integer ... which certainly will look for integers only ... i think char is an int but not Integer type.
what are your views on this ranchers.
|
http://plainoldjavaobject.blogspot.in
|
 |
Martin Vanyavchich
Ranch Hand
Joined: Sep 16, 2008
Posts: 241
|
|
I think Lalit Mehra is right. This compiles:
And what's more, this compiles and runs just fine:
How is this possible?
|
SCJP 6, OCMJD 6, OCPJWSD 6
I no good English.
|
 |
Sahil Kapoor
Ranch Hand
Joined: Sep 12, 2009
Posts: 316
|
|
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9191
|
|
1. Boxing/Unboxing is done by the compiler not JVM.
2. The switch expression is unboxed as given in the spec.
3. The spec also says that the case constants must be compatible with the switch expression. This is why the following code fails to compile
's' is not compatible with the switch expression (as Integer i = 's'; won't compile). Although the switch expression will be unboxed and after that 's' will be compatible with the unboxed value 30, but the compiler also have to ensure that the case constants are compatible with the switch expression before the unboxing takes place...
|
SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
|
 |
Sahil Kapoor
Ranch Hand
Joined: Sep 12, 2009
Posts: 316
|
|
as Integer i = 's'; won't compile
is this statement not valid because of widening-box rules ???
I mean it is too much for the compiler to wide and then box ???
|
 |
Lalit Mehra
Ranch Hand
Joined: Jun 08, 2010
Posts: 369
|
|
as ankit said ...
it is the actual switch expression the JVM matches the case constants with before manipulating it (the expression)
and as I said before ...
Integer i.equals(int i) = false
|
 |
dipayan chatterjee
Ranch Hand
Joined: Oct 03, 2007
Posts: 47
|
|
Hi Lalit and Ankit
thanks for your explainations now the error makes sense . I tried out the same code on MyEclipse and surprisingly it works just fine . I just modified the code a little
the code compiles and runs giving the output " in default "
could you please throw some light on the reason for such change in behaviour when we run the same code using IDE and command prompt
thanks in advance
|
 |
Lalit Mehra
Ranch Hand
Joined: Jun 08, 2010
Posts: 369
|
|
I don't know why is it working. i tried it on netbeans and even before compiling it showed me the error.
It might be because of some IDE platform centric options.
p.s. i have never worked on Eclipse. so can't clarify much on this.
|
 |
Unmesh Chowdhury
Ranch Hand
Joined: Jun 20, 2010
Posts: 44
|
|
Actually, compiler does compatibility test between case constant and the evaluated type of the switch expression, that is, it checks whether the type and the value of the case constant is assignable in the evaluated type of the switch expression. As a result the following codes will compile and run as usual:
|
M.Sc. in CS, OCPJP6 93%
|
 |
Seetharaman Venkatasamy
Ranch Hand
Joined: Jan 28, 2008
Posts: 5575
|
|
Lalit Mehra wrote:
i have never worked on Eclipse. so can't clarify much on this.
though I am an eclipse man, I dont have any answare for this
looking for some comments on this.
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9191
|
|
|
Eclipse uses a different compiler than the normal javac compiler we use from the command prompt. I think Eclipse uses an IBM compiler but I'll have to look into the details to be sure. The compiler used by Eclipse behaves differently than the JDK compiler on many occasions. For SCJP you should always rely on the JDK compiler and not any IDE...
|
 |
Abimaran Kugathasan
Ranch Hand
Joined: Nov 04, 2009
Posts: 2066
|
|
|
Thanks Ankit Garg!
|
|BSc in Electronic Eng| |SCJP 6.0 91%| |SCWCD 5 92%|
|
 |
Pradeep Kr
Greenhorn
Joined: Feb 17, 2010
Posts: 22
|
|
Just to add more dimension to this
above code compile perfectly in sun compiler (javac) why above code works but not switch statement?
I understand switch statement always works on int, and the way I understand, it should first try to convert new Integer(30) to int, instead of trying to convert char 's' to Integer.
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9191
|
|
|
When you use == operator, if one of the operands is a primitive and the other is a wrapper class, the wrapper is unboxed. So in your case i is unboxed to int, then a is promoted to int and then the conversion is done...
|
 |
Lalit Mehra
Ranch Hand
Joined: Jun 08, 2010
Posts: 369
|
|
Ankit Garg wrote:When you use == operator, if one of the operands is a primitive and the other is a wrapper class, the wrapper is unboxed. So in your case i is unboxed to int, then a is promoted to int and then the conversion is done...
Ankit is right ...
wrapper in unboxed to the primitive type always ...
and since char is internally an int .. it is promoted to an int before == checking ...
in case of the switch statement ... since the actual expression is evaluated only before being converted or unboxed or promotion ... this happens
|
 |
Pradeep Kr
Greenhorn
Joined: Feb 17, 2010
Posts: 22
|
|
Lalit Mehra wrote:in case of the switch statement ... since the actual expression is evaluated only before being converted or unboxed or promotion ... this happens
I assume this is not correct behavior, even though we know it is behaving like this. I am trying to understand logic behind this behavior. Is there any logical reason why compiler behave like this.
from the logical thinking, I think switch as multiple if else, may be implementation wise there is difference the way if and switch statement converted into byte code.
Or may be I am thinking too much, I should accept this or move on?
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9191
|
|
Pradeep- Kumar wrote:from the logical thinking, I think switch as multiple if else, may be implementation wise there is difference the way if and switch statement converted into byte code.
Well yes logically you can think of switch as multiple if else. But the rules for if-else don't apply to switch. The case constants are not compared to the switch expression with == operator. Switch statement is a construct in itself. So the case constants need to be compatible with the switch expression, the JLS doesn't say that the case constants must be compatible with the switch expression *after* the switch expression is unboxed...
|
 |
 |
|
|
subject: Box or Unbox
|
|
|