JLS определяет это поведение (создание массива элементов типа, который является типом параметра переменной arity, т.е. если метод vararg равен foo(Bar bar, Baz baz, T...)
, тогда массив, созданный при вызове метода, имеет тип T[]
), если вы найдете правильное место:
С JLS 8.4.1 (в данный момент у сайта Oracle возникли проблемы, мне пришлось использовать Интернет-архив):
Если последний формальный параметр
переменный параметр арности типа T, это
считается определить формальное
параметр типа T []. Метод
затем метод переменной арности.
В противном случае это метод фиксированной арности.
Вызовы метода переменной арности
может содержать более актуальный аргумент
выражения, чем формальные параметры.
Все фактические выражения аргумента
которые не соответствуют формальным
параметры, предшествующие переменной
Параметр арности будет оценен и
результаты сохраняются в массиве
будет передан в метод
вызов (§15.12.4.2).
Из JLS 15.12.4.2:
15.12.4.2 Оценка аргументов Процесс оценки аргумента
список отличается в зависимости от того,
вызываемый метод является фиксированной арностью
метод или метод переменной арности
(§8.4.1).
Если вызываемый метод является
метод переменной арности (§8.4.1) m, это
обязательно имеет n> 0 формальных параметров.
Конечный формальный параметр м
обязательно имеет тип T [] для некоторого T,
и м обязательно вызывается
с k> = 0 фактическими выражениями аргументов.
Если m вызывается с k! = N фактическим
выражения аргумента, или, если m
вызывается с фактическим аргументом k = n
выражения и тип kth
Выражение аргумента не является присваиванием
совместим с T [], то аргумент
список (e1, ..., en-1, en, ... ek) является
оценивается как если бы оно было написано как
(e1, ..., en-1, new T [] {en, ..., ek}).
Выражения аргумента (возможно
переписан как описано выше) сейчас
оценивается для получения значений аргументов.
Каждое значение аргумента соответствует
точно один из п формального метода
параметры.
Выражения аргумента, если таковые имеются,
оценивается по порядку, слева направо
право. Если оценка какого-либо
выражение аргумента завершено
внезапно, то никакая часть какого-либо аргумента
Выражение справа от
были оценены, и метод
вызов завершается внезапно для
Причина та же. Результат оценки
J-е выражение аргумента является J-й
значение аргумента для 1 <= j <= n. оценка
затем продолжает, используя аргумент
значения, как описано ниже. </p>
Поэтому я сохраняю свой первоначальный ответ (см. Ниже).
Я считаю, что ответ в декларации:
public static Object combine(Object... objs)
Компилятор соответствует этому методу, и поэтому для varargs он выделяет Object[]
. Для этого нет причин выделять Integer[]
.
пробный тест:
package com.example.test;
public class Varargs1 {
public static void varargs(Object... objs) {
System.out.println(objs.getClass());
}
public static void main(String[] args) {
varargs("1", "2", "3");
varargs(1, 2, 3);
Integer[] ints = {1,2,3};
varargs(ints); // Eclipse yields the following warning:
/*
* The argument of type Integer[] should explicitly be
* cast to Object[] for the invocation of the varargs
* method varargs(Object...) from type Varargs1.
* It could alternatively be cast to Object for a
* varargs invocation
*/
}
}
который печатает:
class [Ljava.lang.Object;
class [Ljava.lang.Object;
class [Ljava.lang.Integer;
Наконец, если вы хотите, чтобы компилятор был более точным, используйте общие методы:
package com.example.test;
public class Varargs2 {
public static <T> void varargs(T... objs) {
System.out.println(objs.getClass());
}
public static void main(String[] args) {
varargs("1", "2", "3");
varargs(1, 2, 3);
varargs(1, "2", 3); // warning from Eclipse:
/*
* Type safety : A generic array of
* Object&Comparable<?>&Serializable
* is created for a varargs parameter
*/
}
}
который печатает:
class [Ljava.lang.String;
class [Ljava.lang.Integer;
class [Ljava.lang.Comparable;