Почему мы используем автобоксинг и распаковку в Java?


Autoboxing-Это автоматическое преобразование, которое делает компилятор Java между примитивными типами и соответствующей им оболочкой объекта занятия. Например, преобразование int в целое число, double в a Двойной и так далее. Если преобразование идет в другую сторону, это называется распаковка.

Так зачем нам это нужно и почему мы используем автобоксинг и распаковку в Java?

7 60

7 ответов:

требуется некоторый контекст, чтобы полностью понять основную причину этого.

примитивы против классов

примитивные переменные в Java содержат значения (целое число, двоичное число с плавающей запятой двойной точности и т. д.). Потому что эти значения могут иметь разную длину, переменные, содержащие их, также могут иметь разную длину (рассмотрим float и double).

С другой стороны, класс переменные содержат ссылки в случаях. Ссылки обычно реализуются как указатели (или что-то очень похожее на указатели) на многих языках. Эти вещи обычно имеют одинаковый размер, независимо от размеров экземпляров, на которые они ссылаются (Object,String,Integer, etc).

это свойство переменных класса делает ссылки, которые они содержат заменимые (в определенной степени). Это позволяет нам делать то, что мы называем замена: вообще говоря, использовать экземпляр определенного типа в качестве экземпляра другого, связанного типа (использовать String как Object, например).

примитивные переменные не заменимый точно так же, ни друг с другом, ни с Object. Наиболее очевидной причиной этого (но не единственной) является их разница в размерах. Это делает примитивные типы неудобными в этом отношении, но мы все еще нуждаемся в них язык (по причинам, которые в основном сводятся к производительности).

дженерики и стирание типа

универсальные типы-это типы с одним или несколькими параметры типа (точное число называется generic arity). Например,определение универсального типаList<T> имеет параметр типа T, который может быть Object (производства конкретного типаList<Object>),String (List<String>),Integer (List<Integer>) и так на.

универсальные типы намного сложнее, чем не универсальные. Когда они были введены в Java (после его первоначального выпуска), чтобы избежать внесения радикальных изменений в JVM и, возможно, нарушения совместимости со старыми двоичными файлами,создатели Java решили реализовать универсальные типы наименее инвазивным способом: все конкретные типы List<T> фактически компилируются в (двоичный эквивалент)List<Object> (для других типов, может быть что-то кроме Object, но вы получите точку). в этом процессе теряется общая информация о параметрах arity и type, вот почему мы называем его стирания типа.

соединяя их вместе

теперь проблема заключается в сочетании вышеуказанных реалий: если List<T> становится List<Object> во всех случаях, то T всегда должен быть тип, который может быть непосредственно назначен Object. Ничего другого быть не может допустимый. Поскольку, как мы уже говорили,int,float и double не взаимозаменяемы с Object не может быть List<int>,List<float> или List<double> (если только в JVM не существовало значительно более сложной реализации дженериков).

но Java предлагает такие типы, как Integer,Float и Double чего оберните эти примитивы в экземпляры класса, делая их эффективно заменить как Object, таким образом позволяя универсальным типам косвенно работать с примитивы а также (потому что вы можете есть List<Integer>,List<Float>,List<Double> и так далее).

процесс создания Integer С int, a Float С float и так далее, называется бокс. Обратное называется анбоксинг. Потому что каждый раз, когда вы хотите использовать их как Object неудобно, есть случаи, когда язык делает это автоматически - это называется автоупаковка.

Автомобильный Бокс и используется для преобразования примитивных типов данных в объекты класса-оболочки. Класс-оболочка предоставляет широкий диапазон функций, которые должны выполняться на примитивных типах. Наиболее распространенный пример:

int a = 56;
Integer i = a; // Auto Boxing

Это нужны из-за программистов легко иметь возможность напрямую писать код, а JVM позаботится о боксе и распаковке.

авто бокс также пригодится когда мы работаем с Java.утиль.Тип коллекции. Когда мы хотим создать коллекцию примитивных типов, мы не можем непосредственно создать коллекцию примитивного типа, мы можем создать коллекцию только объектов. Например:

ArrayList<int> al = new ArrayList<int>(); // not supported 

ArrayList<Integer> al = new ArrayList<Integer>(); // supported 
al.add(45); //auto Boxing 

Wrapper-Классы

каждый из 8 примитивных типов Java (byte,short,int,float,char,double,boolean,long) имеет отдельный класс оболочки, связанный с ними. Эти классы-оболочки имеют предопределенные методы для предварительной обработки полезные операции с примитивными типами данных.

использование Wrapper-Классы

String s = "45";
int a = Integer.parseInt(s); // sets the value of a to 45.

есть много полезных функций, которые предоставляют классы-оболочки. Проверьте документацию здесь

анбоксинг является противоположностью Auto Boxing, где мы преобразуем объект класса-оболочки обратно в его примитивный тип. Это делается автоматически JVM, так что мы можем использовать классы-оболочки для определенной операции, а затем конвертировать их вернемся к примитивным типам, поскольку примитивы приводят к более быстрой обработке. Например:

Integer s = 45;
int a = s; auto UnBoxing;

в случае коллекций, которые работают с объектами, используется только автоматическая распаковка. Вот как :

ArrayList<Integer> al = new ArrayList<Integer>();
al.add(45);

int a = al.get(0); // returns the object of Integer . Automatically Unboxed . 

примитивные (не объектные) типы имеют там обоснование в эффективности.

примитивные типы int, boolean, double являются непосредственными данными, тогда как Objects-это ссылки. Следовательно, поля (или переменные)

int i;
double x;
Object s;

потребуется локальная память 4+8+8? где для объекта хранится только ссылка (адрес) на память.

использование обертки объекта Integer, Double и другие, можно было бы ввести косвенность, ссылку на некоторый экземпляр Integer / Double в куче памяти.

зачем нужен бокс?

это вопрос относительный характер. В будущем java планируется иметь возможность иметь ArrayList<int>, подъем примитивных типов.

ответ: На данный момент ArrayList работает только для объекта, резервируя место для ссылки на объект и управляя сборкой мусора аналогичным образом. Отсюда универсального типа являются дочерними объектами. Так что если кто-то хотел ArrayList значения с плавающей запятой, нужно было обернуть двойной в двойной объект.

здесь Java отличается от традиционного C++ своими шаблонами: c++ classes vector<string>, vector<int> создаст два продукта компиляции. Дизайн Java пошел на наличие одного ArrayList.класс, не требующий для каждого типа параметра нового скомпилированного продукта.

поэтому без бокса для объекта нужно было бы скомпилировать классы для каждого вхождения типа параметра. В concreto: каждый класс коллекции или контейнера будет нужна версия для объекта, int, double, boolean. Версия для объекта будет обрабатывать все дочерние классы.

фактически, необходимость в такой диверсификации уже существовала в Java SE для IntBuffer, CharBuffer, DoubleBuffer,... которые работают на int, char, double. Это было решено хакерским способом формирование эти источники из общего.

начиная с JDK 5, java добавила две важные функции: autoboxing и autounboxing. Автоупаковка - это процесс, для которого примитивный тип автоматически инкапсулируется в эквивалентную оболочку всякий раз, когда такой объект необходим. Вам не нужно явно создавать объект. Авто-распаковка - это процесс, при котором значение инкапсулированного объекта автоматически извлекается из оболочки типа, когда требуется его значение. Вам не нужно звонить такой метод, как сертификата от его закодированной формы() или doubleValue().

добавление автобоксинга и автоматической распаковки значительно упрощает написание алгоритмов, устраняя приманку вручную бокс и распаковку значений. Это также полезно для избежать ошибок. Это тоже очень важно для дженерики, которые работают только на объекты. Наконец, автобоксинг облегчает работу с Collections Framework.

почему у нас есть (ООН)бокс?

чтобы сделать написание кода, где мы смешиваем примитивы и их объектно-ориентированные (OO) альтернативы более удобными/менее подробными.

почему у нас есть примитивы и их альтернативы OO?

примитивные типы не являются классами (в отличие от C#), поэтому они не являются подклассами Object и не может быть переопределен.

у нас есть примитивы типа int для повышения производительности и Object альтернативы, как Integer для преимуществ программирования OO и как второстепенный момент, чтобы иметь хорошее расположение для служебных констант и методов (целое число.Max_value и Integer.toString(int)).

преимущества OO видны наиболее легко с дженериками (List<Integer>), но не ограничиваются этим, например:

Number getMeSome(boolean wantInt) {

    if (wantInt) {
        return Integer.MAX_VALUE;
    } else {
        return Long.MAX_VALUE;
    }
}

потому что они разные типы, и как удобство. Производительность, вероятно, является причиной наличия примитивных типов.

некоторые структуры данных могут принимать только объекты, без примитивных типов.

пример: ключ в HashMap.

см. этот вопрос для получения дополнительной информации:HashMap и int как ключ

есть и другие веские причины, такие как поле "int" в базе данных, которое также может быть NULL. Int в Java не может быть null ; целочисленная ссылка может. Автобоксинг и распаковка обеспечивают возможность избежать написания постороннего кода в обратном и обратном преобразованиях. далее.