Var-arg объектных массивов против объектного массива - пытается понять вопрос самопроверки SCJP - PullRequest
5 голосов
/ 15 июля 2009

У меня проблемы с пониманием этого вопроса и объяснения ответа на вопрос самопроверки 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 методы выбираются последними. Помни что массивы являются объектами. Наконец, int может быть упакован в целое число, а затем "расширен" до объекта. "

Разбивая это, кто-то может дать дальнейшее определение этому объяснению?

  1. Обычно перегруженные методы var-args выбираются последними.
  2. Массивы - это объекты (я на самом деле понимаю, но почему это относится к этому вопросу).
  3. Int может быть упаковано в Integer, а затем "расширено" до Object.

Спасибо!

Ответы [ 2 ]

6 голосов
/ 15 июля 2009

Книга пытается объяснить, почему первые две перегрузки никогда не выбираются: потому что маркер var-args ... позволяет использовать их только в случае сбоя при любой другой возможной перегрузке. В этом случае этого не происходит - два предложения, начинающиеся с «Запомнить», объясняют, ПОЧЕМУ этого не происходит, почему в первом и последнем случае существуют другие возможные перегрузки (второй случай и его соответствие с третьей перегрузкой). из sifter очевиден): массив - это объект, и int может быть упакован, а затем расширен до Object, поэтому 4-я перегрузка соответствует первому и последнему из вызовов sifter.

4 голосов
/ 15 июля 2009
  1. При попытке определить, какой метод вызывать, компилятор сначала ищет метод, отличный от vararg (например, sifter(Object)), прежде чем рассматривать метод vararg (например, sifter(A[]...)), когда оба метода принадлежат одному и тому же методу. класс (более или менее).

  2. Поскольку массив является Object, вызов sifter(aa) будет соответствовать sifter(Object), следовательно, даже не учитывая sifter(A[]...).

  3. Начиная с Java 5, компилятор может «примитивировать» примитив, то есть преобразовывать примитивные значения (например, int) в соответствующие им Object (например, Integer). Таким образом, для sifter(6) компилятор преобразует int 6 в Integer 6, таким образом, он будет соответствовать методу sifter(Object).

...