Какой код генерирует компилятор для автобокса?
-
03-07-2019 - |
Вопрос
Когда компилятор Java автоматически помещает примитив в класс-оболочку, какой код он генерирует «за кулисами»?Я предполагаю, что он вызывает:
- Метод valueOf() в обертке
- Конструктор оболочки
- Какая-то другая магия?
Решение
Вы можете использовать javap
инструмент, чтобы убедиться в этом сами.Скомпилируйте следующий код:
public class AutoboxingTest
{
public static void main(String []args)
{
Integer a = 3;
int b = a;
}
}
Для компиляции и дизассемблирования:
javac AutoboxingTest.java
javap -c AutoboxingTest
Результат:
Compiled from "AutoboxingTest.java"
public class AutoboxingTest extends java.lang.Object{
public AutoboxingTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: aload_1
6: invokevirtual #3; //Method java/lang/Integer.intValue:()I
9: istore_2
10: return
}
Таким образом, как видите, автобоксинг вызывает статический метод Integer.valueOf()
, и автораспаковка вызывает intValue()
по данному Integer
объект.На самом деле больше ничего нет — это просто синтаксический сахар.
Другие советы
Я придумал модульный тест, который доказывает, что вместо конструктора оболочки вызывается Integer.valueOf().
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import org.junit.Test;
public class Boxing {
@Test
public void boxing() {
assertSame(5, 5);
assertNotSame(1000, 1000);
}
}
Если вы посмотрите документацию API для Целое число#значениеOf(целое), вы увидите, что он был добавлен в JDK 1.5.Во все типы оберток (у которых их еще не было) были добавлены аналогичные методы для поддержки автобокса.Для определенных типов существуют дополнительные требования, описанные в JLS:
Если значение п быть в боксе - это
true
,false
, аbyte
, аchar
В диапазоне\u0000
к\u007f
, илиint
илиshort
число между-128
и127
, тогда пусть р1 и р2 быть результатами любых двух боксерских преобразований п.Всегда бывает так, что р1 == р2. §5.1.7
Интересно отметить, что long
s не подчиняются такому же требованию, хотя значения Long в -128..127
range кэшируются в реализации Sun, как и другие целочисленные типы.
Я также только что обнаружил, что в моей копии Язык программирования Java, там говорится char
значения из \u0000
к \u00ff
кэшируются, но, конечно, верхний предел спецификации составляет \u007f
(и Sun JDK в этом случае соответствует спецификации).
Я бы порекомендовал получить что-то вроде Джад и много декомпилировать код.Вы можете узнать немного больше о том, что на самом деле делает Java.