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

时间:2010-09-15 19:02:29

标签: java scjp

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

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

他们的解释是:

  

考虑一下......如果它试图装箱   首先,该字节将是   转换为字节。现在我们又回来了   试图将字节扩大到长,和   当然,IS-A测试失败了。

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

任何人都可以澄清整个方框并加宽和加宽对我来说,因为在这个问题上,这本书并不完全清楚。

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

5 个答案:

答案 0 :(得分:4)

语言令人困惑。

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

但是,另一方面,你可以这样做:
字节 - >字节 - >对象
因为Byte是一个对象。

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

toLong(Long x)
toObject(Object x)
字节b = 5;

然后这句话将是非法的:
toLong(b)中;
//因为b - >新字节(b) - > new Long(新的Byte(b))是非法的。
AND byte - >长 - >由于编译器的限制,无法完成。

但这句话是合法的:
toObject(b);
//因为b - >新字节(b) - >新对象(新的字节(b))是合法的。

答案 1 :(得分:4)

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

  

Java 5的设计者决定最重要的规则应该是   预先存在的代码应该以它以前的方式运行,所以从那以后   扩展功能已经存在,一种通过调用的方法   扩大不应该失去依赖于新创建的方法   拳击

答案 2 :(得分:3)

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

因此,您必须先扩展(byte - > long),然后框(long - > Long)。

答案 3 :(得分:1)

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

您可以装入一个字节,然后加宽为ObjectNumber

正如你的书所说:

  

我们回到尝试将字节扩展为长


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

byte b = 1;
Long l = b;

b更改为Byte(先装箱),但无法更改为Long,因为字节不是Long的子类。

更多步骤:

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

答案 4 :(得分:1)

从本质上说,规则是你可以加宽然后加宽但不加宽然后框。但是如果拳击然后加宽那么被加宽的类必须与你正在扩展的类在同一继承树中。

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