Когда компилятор Java автоматически делит примитив на класс-оболочку, какой код он генерирует за кулисами? Я думаю, он называет:
- Метод valueOf() на обертке
- Конструктор обертки
- Некоторая другая магия?
Когда компилятор Java автоматически делит примитив на класс-оболочку, какой код он генерирует за кулисами? Я думаю, он называет:
Вы можете использовать инструмент 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
}
Таким образом, как вы можете видеть, autoboxing вызывает статический метод Integer.valueOf()
, а autounbing вызывает intValue()
для данного объекта Integer
. Нет ничего другого, на самом деле - это просто синтаксический сахар.
Я придумал unit test, который доказывает, что вместо конструктора обертки вызывается 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 для Integer # valueOf (int), вы увидите, что он был добавлен в JDK 1.5. Все типы обертки (которые еще не имели их) использовали аналогичные методы для поддержки автобоксинга. Для определенных типов есть дополнительное требование, как описано в JLS:
Если значение p, помещенное в квадрат, равно
true
,false
, abyte
, achar
в диапазоне от\u0000
до\u007f
или числоint
илиshort
между-128
и127
, то пусть r1 и r2 - результаты любых двух бокс-преобразований p. Всегда бывает, что r1 == r2. §5.1.7
Интересно отметить, что long
не подчиняются одному и тому же требованию, хотя значения Long в диапазоне -128..127
кэшируются в реализации Sun, как и другие интегральные типы.
Я также только что обнаружил, что в моей копии Язык программирования Java он говорит char
значения от \u0000
до \u00ff
кэшируются, но, конечно, верхний предел для спецификации равен \u007f
(а Sun JDK соответствует спецификации в этом случае).
Я бы рекомендовал получить что-то вроде jad и много декомпилировать код. Вы можете узнать немного о том, что на самом деле делает Java.