Какой код генерирует компилятор для автобокса?

StackOverflow https://stackoverflow.com/questions/408661

  •  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

Интересно отметить, что longs не подчиняются такому же требованию, хотя значения Long в -128..127 range кэшируются в реализации Sun, как и другие целочисленные типы.

Я также только что обнаружил, что в моей копии Язык программирования Java, там говорится char значения из \u0000 к \u00ff кэшируются, но, конечно, верхний предел спецификации составляет \u007f (и Sun JDK в этом случае соответствует спецификации).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top