Ответ 1
В вашем коде нет автобоксинга. Фактически, учитывая:
public static void requireInRange(int index, Object[] array) {
...
}
int[] anArray = {3, 4, 2};
requireInRange(3, anArray); // DOES NOT COMPILE!!!
В то время как int
может быть autoboxed к Integer
, int[]
НЕ получает autoboxed до Integer[]
от Java. Вы можете писать библиотечные функции для этого, но язык не будет облегчать это преобразование.
Это на самом деле является источником многих путаниц в отношении, например, Arrays.asList(anIntArray)
"сломан", потому что вместо возврата List<Integer>
то, что возвращается, на самом деле является одноэлементным List<int[]>
.
Но как насчет производительности???
Цитата из Руководство по языку Java/Autoboxing:
Нельзя использовать автобоксинг и распаковку для научных вычислений или другой чувствительный к производительности численный код.
Integer
не является заменойint
; autoboxing и unboxing размывают различие между примитивными типами и ссылочными типами, но они не устраняют его.
Короче говоря, всякий раз, когда происходит автобоксинг, производительность определенно занимает немного хита. Некоторые вещи помогают облегчить это, например. механизм кеширования, встроенный в эти типы. Вот почему вы получаете следующее:
System.out.println(
((Integer) 0) == ((Integer) 0)
);
// true
System.out.println(
((Integer) 10000) == ((Integer) 10000)
);
// false (implementation-specific)
Что произошло здесь, когда 0
автоматически помещается в бокс, новый экземпляр Integer
фактически не создается: значения в определенном диапазоне кэшируются для целей autoboxing, чтобы помочь производительности. 10000
в большинстве случаев реализации, вероятно, выпадает из этого диапазона, но некоторые реализации JVM позволяют вам указать диапазон кеша, если это необходимо.
Но я просто хочу получить длину массива!!!
Существует множество способов облегчить работу requireInRange
с любыми типами массивов. К сожалению, работа с Java-массивом примитивов часто означает много повторений. Это означает предоставление перегрузок для int[]
, boolean[]
, byte[]
, Object[]
и т.д. Отдельно.
Более краткий вариант - использовать отражение, но у этого есть свои плюсы и минусы. Вообще говоря, отражение не должно быть предпочтительным решением для большинства сценариев.
Сказав, что java.lang.reflect.Array
имеет int getLength(Object array)
static
, который может возвращать длину ЛЮБОГО массива. Это не типы (например, большинство механизмов отражения); передавая компиляцию без массива, но бросает IllegalArgumentException
во время выполнения.
Связанные вопросы
- Управление очень повторяющимся кодом и документацией в Java - ( "вдохновлено"
java.util.Arrays
)