Какой код генерирует компилятор для автобокса? - PullRequest
29 голосов
/ 03 января 2009

Когда компилятор Java автоматически помещает примитив в класс-оболочку, какой код он генерирует за кулисами? Я предполагаю, что это вызывает:

  • Метод valueOf () в оболочке
  • Конструктор оболочки
  • Какая-то другая магия?

Ответы [ 4 ]

45 голосов
/ 03 января 2009

Вы можете использовать инструмент 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 объекта. На самом деле больше ничего нет - это просто синтаксический сахар.

9 голосов
/ 04 января 2009

Я придумал модульный тест, который доказывает, что 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);
    }
}
4 голосов
/ 04 января 2009

Если вы посмотрите документацию API для Integer # valueOf (int) , вы увидите, что он был добавлен в JDK 1.5. Все типы-обертки (у которых их еще не было) были добавлены аналогичные методы для поддержки автобокса. Для определенных типов существует дополнительное требование, как описано в JLS:

Если значение p в штучной упаковке равно true, false, byte, char в диапазоне от \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 соответствует спецификации в этом случае).

1 голос
/ 03 января 2009

Я бы порекомендовал получить что-то вроде jad и много раз декомпилировать код. Вы можете узнать немного больше о том, что на самом деле делает Java.

...