Win a copy of Learn Spring Security (video course) this week in the Spring forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Box or Unbox

 
Sahil Kapoor
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 !!!
 
Ireneusz Kordal
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 384
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think Lalit Mehra is right. This compiles:


And what's more, this compiles and runs just fine:



How is this possible?
 
Sahil Kapoor
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Ankit Garg
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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...
 
Sahil Kapoor
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 384
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 384
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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:


 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Java Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 2066
Clojure IntelliJ IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Ankit Garg!
 
Pradeep Kr
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 384
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 22
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 9509
22
Android Google Web Toolkit Hibernate IntelliJ IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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...
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic