SCJP: can't widen and then box, but you can box and then widen

走远了吗. 提交于 2019-11-29 04:48:32

the language is confusing.

Basically you can't go in this fashion:
byte -> Byte -> Long
because Byte and Long don't share an is-a relationship.
So, it tries to do this:
byte -> long -> Long
But it can't do that either(apparently due to compiler limitations). So, it fails and throws an error.

But, on the other hand you CAN do this:
byte -> Byte -> Object
because Byte is-an Object.

consider 2 functions and a byte variable:

toLong(Long x)
toObject(Object x)
byte b = 5;

Then this statement will be illegal:
toLong(b);
// because b -> new Byte(b) -> new Long(new Byte(b)) is illegal.
AND byte -> long -> Long can't be done due to compiler limitations.

but this statement is legal:
toObject(b);
// because b -> new Byte(b) -> new Object(new Byte(b)) is legal.

Bipin

The reason why "widening then boxing" is not allowed may be because of the following reason (page 249 of the SCJP book):

Java 5's designers decided that the most important rule should be that preexisting code should function the way it used to, so since widening capability already existed,a method that is invoked via widening shouldn't lose out to a newly created method that relies on boxing

Basically what this means is that widening only works with primitive types, not the wrappers. If you box first, you get a wrapper (byte -> Byte). But the wrappers - Byte, Double, Float, Integer, Long and Short do not have any inheritance relationship (IS-A). A Long parameter can't accept a Byte for instance.

So you must widen first (byte -> long) and then box (long -> Long).

It isn't a widening because Byte doesn't fit in a Long. That's why it doesn't works.

You can box into a Byte and then widen into an Object or a Number.

As your book says :

we're back to trying to widen a Byte to a Long


In your case, I suppose the code looks like this :

byte b = 1;
Long l = b;

b is changed into a Byte (boxing first) but can't be changed into a Long because Byte isn't a subclass of Long.

In more steps :

byte b = 1;
Byte byteB = b; //works
Long l = byteB; //doesn't work

In essence the rules stand that you can box then widen but not widen then box. However if boxing then widening then the class being widened must be in the same inheritance tree as the class you are widening to.

Whilst the example shown is trying to box then widen, the reason it is invalid is because Byte is not a Long, ie they are not in the same inheritance tree. However if the example used Byte and Numeric, then you it would be valid to Box byte to Byte and then widen Byte to Numeric as Byte IS-A Numeric (they ARE in the same inheritance tree)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!