This week's book giveaway is in the Mac OS forum.
We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes something odd with boxing/widening I can't figure out Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "something odd with boxing/widening I can Watch "something odd with boxing/widening I can New topic
Author

something odd with boxing/widening I can't figure out

neil walker
Greenhorn

Joined: Jan 24, 2008
Posts: 19
Hello,
Can anyone explain the reasons behind the following two pieces of code relating to Number classes as I simply can't. I know it must be something to do with boxing, widening, narrowing, etc. but I'm not really sure:



The Long assignment compiles fine but the byte fails. I assume this is because the 100 is an integer expression and the Long parameter can widen it from int to long, but the Byte won't narrow it? If that's the case that's really annoying as you can happily do something like 'byte b=100'

However, do the same again, but as follows:


This time the opposite happens: the Byte will compile and the Long fails to compile. I thought originally it must be to do with not being able to widen and box in the case of Long, but then Byte compiles fine.

Many thanks if someone can explain

[ January 24, 2008: Message edited by: neil walker ]
[ January 24, 2008: Message edited by: neil walker ]
Ali Khalfan
Ranch Hand

Joined: Nov 03, 2007
Posts: 126
I'll try to clarify this here, maybe someone'll correct me but i'll go ahead and say for the first part



the 100 is an integer by default, so this is like you are calling a constructor of Byte(int ), since there isn't any you'll get an error

a solution would be something like:




as for new Long(100), the int will simply widen to long and there is a constructor of Long(long) so it'll work.



As for the second scenario:

Byte b = 100; //this is straight forward auto-boxing
you can divide the above into 2 like saying:
byte b_temp = 100;
Byte b = new Byte(b_temp); //only autoboxing


Now for Long g = 100;

you are saying

long g_temp = 100; //widening

then
Long g = new Long(g_temp); //autoboxing

You cannot widen and autobox so this will return a compiler error.


Someone correct me if i'm wrong
Srinivas Kollaparthi
Greenhorn

Joined: Jan 19, 2008
Posts: 11
For First one,


Byte b= new Byte(100);
Long d=new Long(100);


Byte class has constructors.One takes String and Other takes primitive byte value.

as 100 is an int, new Byte(100) does not compile.
So Change it to :
(1) Byte b = new Byte((byte)100);
or
(2) byte b=100;
Byte bobj= new Byte(b);

Similarly Long Constructor takes either String or long value.
An int value can be implicitly cast to long.
So, Long d=new Long(100); compiles fine.

For the Second one,

Byte b=100;
Long d=100;


These should be like this.

Long ld=100L;
For byte, the assigned value range should between -128 to 127.
Byte b=100; // compiles
Byte b=130; // Doesn't compile.
neil walker
Greenhorn

Joined: Jan 24, 2008
Posts: 19
hello,
Thanks, for the first part, the answer is how I thought, but for the second I still don't get why the integer 100 can be boxed to a byte (as in Byte b=100), and why Long l=100 cannot. Surely both are applying boxing and primitive conversion.

tbh, I'm reading the SCJP study guide and this fixation on tripping you up with largely unrequired trivial knowledge about compiler errors is both annoying me and putting me right off the java language, which as far as I am concerned should be about making things simple and consistent - both of which are not when it comes to autoboxing, reference variable comparisons, etc. I wish the java developers would see reason on how all these rules are stifling the language. Sorry for the rant, btw!
Sunny Jain
Ranch Hand

Joined: Jul 23, 2007
Posts: 433

Hi Neil,

Just chill let me try to explain..May be this can help.!!!
when you write :

byte b = 120;

its compiles fine..!! why because compiler see that int 120 in in RANGE of byte..

Now when you write
byte b = 150;

Compiler complains since 150 is out of RANGE..!!

Now lets come to your question :
Part 1 :
Byte b = new Byte(100);

When ever compiler encounters new keyword, it let the Object creation on JVM..!! so in case of new Object..Objects are created at run time..!! so according to compiler point of view:

Byte b = new Byte(int);

Here int may or may not be in the RANGE of byte, if it is in range then its ok, if it is not then !!! SCARY THINGS!!!..so as a friend compiler wont let you to write something that has possibility of crashing..that why it gives you an error..
in case of

Long l = new Long(int);

now whatsoever be the value of int ,it ALWAYS be in the RANGE of long..so compiler allows..!!!

Second Part :

Byte b = 100;

in this case Object is created at the compile time, so compiler can verify here the range of int..! in this case as the int is in RANGE so it allows.... int ---> byte -->Byte

Long l = 100 ;

Since in the case int is in RANGE and implicit cast is possible so I think compiler should allow:

int --- > long ----> Long

so I agree that its a BUG..!!! otherwise i will eagerly wait till some one comes and give some explanations here..!!!


Thanks and Regards,
SCJP 1.5 (90%), SCWCD 1.5 (85%), The Jovial Java, java.util.concurrent tutorial
neil walker
Greenhorn

Joined: Jan 24, 2008
Posts: 19
Well, I'm happy with the first part (though I can't see how a compiler can create an object, but I get what you're saying about being able to do a range check at runtime or compile time).

As for the second:
Byte b=100;
Long d=100;

I'd be happy with a compiler bug but somehow I suspect there's an answer that will probably not make any logical sense to me!
Sunny Jain
Ranch Hand

Joined: Jul 23, 2007
Posts: 433

lets wait till some great guy reply here..!!!
Prasun Howlader
Ranch Hand

Joined: Oct 21, 2007
Posts: 89
Long d = 100;

This line produce compile time error because you cannot widen from one wrapper type to another. In this case 100 becomes Integer and you assign Interger to Long which generate error.


"Control time instead of letting time control you."
Manish Khurana
Greenhorn

Joined: Jan 26, 2008
Posts: 23
I could be wrong but here is what I think.

Byte b=100;

whhic is Box(byte b=100)
here you are just adding boxing to compiler's prevoious duties. Since it itimplicitlycasts down for you when you put integer literals in byte char or short.It wont complain if it knows that what you are entering is within limits.
Its kinda exception to the rule as with Objects we always cast when going from Superclass to subclass.

Remember though we always get an int with any expression of intsized or smaller variables.
so if
byte t=32;
byte b=56;
s=(Byte)t+b;
it helps us out little bit with asignment statements but then stops helping us when it calculates any expression.




Long d=100;

It involves 2 things widening and boxing that is what compiler cannot do. I suspect if it was Long d=100L it would work. I can box and widen which works as subclass is A superclass.
neil walker
Greenhorn

Joined: Jan 24, 2008
Posts: 19
ok, thanks, I think I understand. But I don't agree

Don't you think that with all these variations on how numbers and equality is handled in java (not just numbers, but strings) is making the language a joke? the whole point, I think, is that things should be simple and consistent. The two statements above should produce the same result, no matter what internal reasons say otherwise (you don't get any of these problems, for example, in c#). The same goes for assigning a float literal to a float, it should work if the number is ok to fit.

Then there is the case of using == on number objects producing different results depending on whether the value is more or less than 127. Just crazy if you ask me.

Then you move onto strings, depending on how you create and use them you get different results when you use ==. Yes, I know strings are references but Strings, like numbers, are treated differently which can be seen by the way you can initialise them, concatenate strings, auto-boxing, etc. I can't remember one single instance when I've needed to compare the reference of strings or number objects, all I want to do with strings when comparisons are concerned is check for equality and using .equals() is not how it should be done as it's ugly and unintuitive. I have a simple solution for this. Overload the == for strings and number objects and backwards compatibility can be kept in the same way as it's always done with the -source flag, then make the compile a bit more intuitive and allow number literals to be assigned to variables if they fit.

I guess this is digressing from the SCJP, but not really as fixing these faults as I see it means the exam is better because it might just start to focus on whether people know java, not know how to spot silly compiler errors hidden in code.
Sunny Jain
Ranch Hand

Joined: Jul 23, 2007
Posts: 433

Hi Neil,

I seems to be agree with your points..JAVA 5 has given a lot of new features ..but it adds to lots to learning..!! but from my point of view..a computer language should be logical..Here we have to learn thousand rules just to learn a simple concept of autoboxing...!!
I am afraid one day learning JAVA will be as difficult as learning Egyptian symbols..!! Anyways I think of your problem, and I am ready to give you one solution,but you need to learn one rule:

In JAVA 5, we can not WIDEN and BOX Together...!!!

Now in

Long l = 100;

In this case 100 is an integer..so first we have to widen it to long then we have to box long to Long...!!
so compiler complain..

Long l = new Long(100);

Here we are widening int(100) to long..but we are not boxing it...!! as we have used new keyword here..so we have explicitly defined the Object creation syntax..

so compile successfully...!!!

now
Byte b = new Byte(100)..

this i already explain you why it can not be compile..!!

now come to following:

Byte b = 100;

Here we have int 100....we are not widening it...infact we are narrowing it..but we call it implicit casting..!!
and since this implicit casting is in range..and the object will be created at compile time..so it works..
so here we can say that..
implicit casting(with in range) + Boxing is acceptable..!!

But again one thing concern me..!!
suppose the following condition..

public static void printMe(Byte b) { }

public static void main(String... args)
{
printMe(100);

}

well I dont have Java 5 right now on my computer..!! so i can not check this..but i am pretty sure ..that it does not work..!!!
 
GeeCON Prague 2014
 
subject: something odd with boxing/widening I can't figure out