Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Автоупаковка


Как любой программист Java знает, невозможно поместить int (или другое примитивное значение) в набор. Наборы могут только содержать ссылки на объект, таким образом, необходимо упаковать примитивные значения в соответствующий класс обертки (который является Integer в случае int). Когда Вы вынимаете объект из набора, Вы добираетесь Integer то, что Вы вставляете; если Вы нуждаетесь int, следует распаковать Integer использование intValue метод. Вся эта упаковка и распаковывание является болью, и загромождает Ваш код. Автоупаковка и распаковывание функции автоматизируют процесс, устраняя боль и помеху.

Следующий пример иллюстрирует автоупаковку и распаковывание, наряду с обобщениями и циклом foreach. В простых десяти строки кода это вычисляет и печатает расположенную в алфавитном порядке таблицу частот слов, появляющихся на командной строке.

import java.util.*;

// Prints a frequency table of the words on the command line
public class Frequency {
   public static void main(String[] args) {
      Map<String, Integer> m = new TreeMap<String, Integer>();
      for (String word : args) {
          Integer freq = m.get(word);
          m.put(word, (freq == null ? 1 : freq + 1));
      }
      System.out.println(m);
   }
}

java Frequency if it is to be it is up to me to do the watusi
{be=1, do=1, if=1, is=2, it=2, me=1, the=1, to=3, up=1, watusi=1}

Программа сначала объявляет карту от String к Integer, соединение числа раз слово происходит на командной строке со словом. Затем это выполняет итерации по каждому слову на командной строке. Для каждого слова это ищет слово в карте. Затем это помещает пересмотренную запись для слова в карту. Строка, которая делает это (выделенный в зеленом) содержит и автоупаковку и распаковывание. Чтобы вычислить новое значение, чтобы связаться со словом, сначала это смотрит на текущую стоимость (freq). Если это - нуль, это - первое возникновение слова, таким образом, это помещает 1 в карту. Иначе, это добавляет 1 к числу предшествующих возникновений и помещает то значение в карту. Но конечно невозможно поместить int в карту, и при этом невозможно добавить тот к Integer. То, что действительно происходит, является этим: Чтобы добавить 1 к freq, это автоматически распаковывается, приводя к выражению типа int. Так как оба из альтернативных выражений в условном выражении имеют тип int, так также условное выражение непосредственно. Чтобы поместить это int значение в карту, это автоматически упаковывается в Integer.

Результат всего этого волшебства состоит в том, что можно в значительной степени проигнорировать различие между int и Integer, с несколькими протестами. Integer у выражения может быть a null значение. Если Ваша программа попытается автораспаковать нуль, то она бросит a NullPointerException. == оператор выполняет ссылочные сравнения идентификационных данных на Integer выражения и сравнения равенства значения на int выражения. Наконец, есть затраты производительности, связанные с упаковкой и распаковыванием, даже если это делается автоматически.

Вот является другой пример программы обладающей автоупаковкой и распаковыванием. Это - статическая фабрика, которая берет int массив и возвраты a List из Integer поддержанный массивом. В простых десяти строки кода этот метод обеспечивает полное богатство List интерфейс на int массив. Все изменения к списку пишут через в массив и наоборот. Строки, которые используют автоупаковку или распаковывание, выделяются в зеленом:

// List adapter for primitive int array
public static List<Integer> asList(final int[] a) {
    return new AbstractList<Integer>() {
        public Integer get(int i) { return a[i]; }
        // Throws NullPointerException if val == null
        public Integer set(int i, Integer val) {
            Integer oldVal = a[i];
            a[i] = val;
            return oldVal;
        }
        public int size() { return a.length; }
    };
}

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

Так, когда следует использовать автоупаковку и распаковывание? Используйте их только, когда есть "несоответствие импеданса" между ссылочными типами и примитивами, например, когда необходимо поместить численные значения в набор. Не уместно использовать автоупаковку и распаковывание для научных вычислений, или другой чувствительный к производительности числовой код. Integer не замена int; автоупаковка и распаковывание размытости различие между типами примитивов и ссылочными типами, но они не устраняют это.


Oracle и/или его филиалы Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами