SCJP:不能加宽然后盒子,但你可以盒子然后加宽

我正在攻读SCJP考试,我遇到了一个我无法真正解决的问题。

这本书说你不能加宽然后装箱,但你可以装盒然后加宽。 无法框的示例是期望Long的方法,并且使用字节调用该方法。

他们的解释是:

想一想……如果它先尝试先打包,那么该字节就会被转换为字节。 现在我们又回到尝试将字节扩展为Long,当然,IS-A测试失败了。

但这听起来像盒子,然后加宽而不是加宽,然后盒子给我。

任何人都可以澄清整个盒子并扩大与扩大和盒子对我来说因为它本来就不是很清楚这个问题。

编辑:澄清一下:我在谈论SCJP sun认证程序员的第252页和第253页,用于java 6书。 http://books.google.be/books?id=Eh5NcvegzMkC&pg=PA252#v=onepage&q&f=false

语言令人困惑。

基本上你不能以这种方式去:
byte – > Byte – > Long
因为Byte和Long不分享is-a关系。
所以,它试图这样做:
byte – > long – > Long
但它也不能这样做(显然是由于编译器的限制)。 因此,它失败并抛出错误。

但是,另一方面,你可以做到这一点:
byte – > Byte – > Object
因为Byte是一个对象。

考虑2个函数和一个字节变量:

to Long(长x)
toObject(对象x)
字节b = 5;

那么这句话将是非法的:
toLong(b)中;
//因为b – > new Byte(b) – > new Long(new Byte(b))是非法的。
AND byte – > long – >由于编译器的限制,无法完成。

但这句话是合法的:
toObject(b)中;
//因为b – > new Byte(b) – > new Object(new Byte(b))是合法的。

不允许“扩大拳击”的原因可能是由于以下原因(SCJP书的第249页):

Java 5的设计者认为最重要的规则应该是预先存在的代码应该像以前那样运行,所以由于已经存在扩展function,通过扩展调用的方法不应该丢失到依赖于装箱的新创建的方法

基本上这意味着扩展只适用于原始类型,而不是包装器。 如果你先装箱,你会得到一个包装器( byte – > Byte )。 但是包装器ByteDoubleFloatIntegerLongShort没有任何inheritance关系(IS-A)。 例如, Long参数不能接受Byte

所以你必须首先加宽( byte – > long )然后加宽( long – > Long )。

这不是一个扩大,因为Byte不适合Long。 这就是为什么它不起作用。

您可以装入字节,然后扩展为ObjectNumber

正如你的书所说:

我们又回到了试图将一个字节扩大到一个长


在您的情况下,我认为代码如下所示:

 byte b = 1; Long l = b; 

b被更改为Byte (先装箱)但不能更改为Long因为Byte不是Long的子类。

在更多步骤中:

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

从本质上讲,规则是你可以加宽然后加宽但不加宽然后框。 但是,如果拳击然后加宽,则扩展的类必须与您正在扩展的类位于同一inheritance树中。

虽然显示的示例是试图加宽然后加宽,但它无效的原因是因为字节不是Long,即它们不在同一inheritance树中。 但是,如果示例使用Byte和Numeric,则将字节Box字节设置为Byte然后将Byte扩展为Numeric作为字节IS-A数字(它们位于同一inheritance树中)是有效的