对象数组的 Var-arg 与对象数组——试图理解 SCJP 自测问题
我无法理解这个问题以及 SCJP 1.6 自测问题答案的解释。 问题来了:
class A { }
class B extends A { }
public class ComingThru {
static String s = "-";
public static void main(String[] args) {
A[] aa = new A[2];
B[] ba = new B[2];
sifter(aa);
sifter(ba);
sifter(7);
System.out.println(s);
}
static void sifter(A[]... a2) { s += "1"; }
static void sifter(B[]... b1) { s += "2"; }
static void sifter(B[] b1) { s += "3"; }
static void sifter(Object o) { s += "4"; }
}
结果是什么? 答案是-434,但让我困惑的是书中的解释。 它与本章前面解释该概念的方式有很大不同。
“一般来说,重载的 var-args 最后选择方法。 请记住 数组是对象。 最后,一个整数 可以装箱为一个整数,然后 “扩大”为对象。”
将其拆分,有人可以进一步定义该解释吗?
- 一般来说,最后选择重载的 var-args 方法。
- 数组是对象(我实际上明白了这一点,但为什么这与这个问题相关) 可以将int
- 装箱为 Integer,然后“扩展”为 Object
谢谢!
I'm having trouble understanding this question, and the explanation of the answer for an SCJP 1.6 self test question. Here is the problem:
class A { }
class B extends A { }
public class ComingThru {
static String s = "-";
public static void main(String[] args) {
A[] aa = new A[2];
B[] ba = new B[2];
sifter(aa);
sifter(ba);
sifter(7);
System.out.println(s);
}
static void sifter(A[]... a2) { s += "1"; }
static void sifter(B[]... b1) { s += "2"; }
static void sifter(B[] b1) { s += "3"; }
static void sifter(Object o) { s += "4"; }
}
What is the result? The answer is -434, but what throws me off is the book's explanation. It is vastly different than how the concept was explained earlier in the chapter.
"In general, overloaded var-args
methods are chosen last. Remember that
arrays are objects. Finally, an int
can be boxed to an Integer and then
"widened" to an Object."
Splitting that up, can someone please further define that explanation?
- In general, overloaded var-args methods are chosen last.
- Arrays are objects (I actually get that, but why is that relevant to this question).
- An int can be boxed to an Integer and then "widened" to an Object.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
本书试图解释为什么前两个重载从未被选择:因为 var-args 标记
...
使它们仅在所有其他可能的重载失败时才使用。 在这种情况下,这不会发生——以“记住”开头的两个句子解释了为什么它不会发生,为什么在第一个和最后一个情况下存在其他可能的重载(第二个情况及其与第三个重载的匹配) sifter 是显而易见的):数组是一个对象,并且 int 可以装箱然后扩大为对象,因此第四个重载与对 sifter 的调用的第一个和最后一个相匹配。The book is trying to explain why the first two overloads are never selected: because the var-args marker
...
makes them be used only if every other possible overload fails. In this case, this doesn't happen -- the two sentences starting with "Remember" is explaining WHY it doesn't happen, why other possible overloads exists in the first and last case (the second case and its match with the 3rd overload of sifter is obvious): an array is an object, and an int can be boxened then widened to an Object, so the 4th overload matches the first and last ones of the calls to sifter.当尝试确定要调用哪个方法时,编译器首先查找非可变参数方法(例如
sifter(Object)
),然后再考虑可变参数方法(例如sifter(A[]. ..)
),当两个方法属于同一个类(或多或少)时。由于数组是一个
对象
,sifter(aa)
的调用将匹配sifter(Object)
,因此甚至不考虑< code>sifter(A[]...).从Java 5开始,编译器可以“装箱”原语,即将原语值(例如
int
)转换为其相应的Object
(例如Integer
)代码>)。 因此,对于sifter(6)
,编译器将int 6
转换为Integer 6
,因此它会匹配sifter(Object )
方法。When attempting to determine which method to invoke, the compiler first looks for non vararg method (e.g.
sifter(Object)
) before considering a vararg one (e.g.sifter(A[]...)
), when both of the methods belong to the same class (more or less).Since an array is an
Object
, the invocation ofsifter(aa)
will matchsifter(Object)
, hence not even consideringsifter(A[]...)
.Starting from Java 5, the compiler may "box" primitive, i.e. convert primitive values (e.g.
int
) to their correspondingObject
(e.g.Integer
). So forsifter(6)
, the compiler converts theint 6
into anInteger 6
, thus it would match thesifter(Object)
method.