В объявлении метода m указывается, что ему должен передаваться параметр типа Integer. В методе main целочисленное значение 199 передается методу m в качестве параметра. В итоге происходит автоупаковка этого целочисленного значения. Далее в программе вызывается метод m2 , возвращающий целочисленное значения 10. Это значение присваивается переменной ссылки на объект iOb в методе main . А поскольку объект iOb относится к типу Integer, то целочисленное значение, возвращаемое методом m2 , автоматически упаковывается. Затем в методе main вызывается метод m3 . Он возвращает объект типа Integer, который посредством автораспаковки преобразуется в тип int. И наконец, в методе main вызывается метод Math. sqrt , которому в качестве аргумента передается объект iOb. В данном случае происходит автораспаковка данного объекта, а его значение продвигается к типу double, поскольку параметр именно этого типа должен быть передан методу Math. sqrt . Автоупаковка и автораспаковка в выражениях
Автоупаковка и автораспаковка выполняются всякий раз, когда объект необходимо преобразовать в простой тип, а простой тип — в объект. Так, автораспаковка производится при вычислении выражений, и если требуется, то результат вычисления упаковывается. Рассмотрим в качестве примера приведенную ниже программу. // Автоупаковка и автораспаковка в выражениях. class AutoBox3 { public static void main(String args[]) { Integer iOb, i0b2; int i; iOb = 99; System.out.println("Original value of iOb: " + iOb); // В следующем выражении объект iOb автоматически // распаковывается, производятся вычисления, а результат // снова упаковывается в объект iOb. ++iOb; System.out.println("After ++iOb: и + iOb); // В последующем выражении производится автораспаковка // объекта iOb, к полученному значению прибавляется число 10, // а результат снова упаковывается в объект iOb. iOb += 10; System.out .println ("After iOb +=? 10: " + iOb) ; //И в следующем выражении объект iOb автоматически // распаковывается, выполняются вычисления, а результат // снова упаковывается в объект iOb. iOb2 = iOb + (iOb / 3); System.out.println("iOb2 after expression: " + iOb2); // А в этом случае вычисляется то же самое выражение, // но повторная упаковка не производится, i = iOb + (iOb / 3); System.out.println("i after expression: " + i); } }
Выполнение этой программы дает следующий результат: Original value of iOb: 99 After ++iOb: 100 After iOb += 10: 110 iOb2 after expression: 146 i after expression: 146
В данной программе особое внимание обратите на следующую строку кода: ++iOb;
В ней значение объекта iOb должно быть увеличено на единицу. Происходит это следующим образом: объект iOb распаковывается, полученное значение инкрементируется, а результат снова упаковывается в объект iOb.
Благодаря автораспаковке объекты оболочек целочисленных типов, например Integer, можно использовать в операторах switch. В качестве примера рассмотрим следующий фрагмент кода: Integer iOb = 2; switch(iOb) { case 1: System.out.println("one") ; break; case 2: System.out.println("two"); break; default: System.out.println("error") ; }
При вычислении выражения в операторе switch объект iOb распаковывается и последующей обработке подвергается значение типа int, упакованное в этом объекте.
Как следует из приведенных выше примеров, выражения, в которых применяются объекты оболочек простых типов, становятся интуитивно понятными благодаря автоупаковке и автораспаковке. До появления версии JDK 5 для достижения аналогичного результата в программе приходилось прибегать к приведению типов и вызовам специальных методов вроде intValue . Предупреждение относительно автоупаковки и автораспаковки
Теперь, когда автоупаковка и автораспаковка предельно упрощают обращение с оболочками простых типов, может возникнуть сильное искушение пользоваться вместо простых типов только их оболочками, например Integer или Double. Так, например, автоупаковка и автораспаковка позволяют создавать код, аналогичный приведенному ниже. // Неоправданное использование автоупаковки и автораспаковки. Double а, Ь, с; а = 10.2; b = 11.4; с = 9.8; Double avg = (a + b + c)./3;