В Java 5.0, классы-оболочки стали проще в использовании. Java 5.0 представила автоматическое преобразование между примитивным типом и соответствующим классом-оболочкой.
От примитивного типа к нему класс оболочки корректов называется autoboxing, обратный процесс называется распаковкой. Автосообщение и распаковка также применяются к вызовам методов. Например, вы можете передать аргумент типа int методу, который имеет формальный параметр типа Integer.
Исключено исключение NullpointerException При освобождении ссылки на нулевой класс-оболочку на свой примитивный тип. Например, код будет скомпилирован, но во время выполнения он выкинет исключение NullpointerException.
Long L = null; long l = L; ...
Конверсия бокса преобразует значения примитивного типа в соответствующие значения ссылочного типа. Но примитивные типы не могут быть расширены/сужены к классам Wrapper и наоборот. Например,
байт b = 43; Целое число I1 = 23; // Постоянное целочисленное значение Целое число I2 = (int) b; // Присвоение типа int Long L1 = 23; // компилируем ошибку, потому что 23 - целое значение Long L2 = (Long) 23; // не может отличать целочисленное значение от длинного класса оболочки Long L3 = 23L; Длинный L4 = (длинный) 23;
Это ограничение также применяется к вызову методы:
public class MyClass
{
public void method(Long i)
{
System.out.println("Here");
}
public static void main(String[] args)
{
MyClass s = new MyClasslass();
//s.method(12);
// error s.method(12L);
// ok
}
}
•When invoking a method from multiple overloading methods, For the matching method process, the Java compiler will perferance the order of primitive types (Widening Primitive Conversion), wrapper class (Boxing Conversion), and var-args. For example,
public class MyClass
{
public void method(Long x, Long y)
{
System.out.println("method(Long x, Long y)");
}
public void method(long x, long y)
{
System.out.println("method(long x, long y)");
}
public void method(long... x)
{
System.out.println("method(long... x)");
}
public static void main(String[] args)
{
long x, y;
x = y = 0;
MyClass s = new MyClass();
s.method(x, y);
}
}
В результате method(long x, long y)
. Компилятор Java будет проверять соответствующие примитивные типы, затем он будет искать типы Wrapper.
public class MyClass
{
public void method(Long x, Long y)
{
System.out.println("method(Long x, Long y)");
}
public void method(int x, int y)
{
System.out.println("method(int x, int y)");
}
public void method(long... x)
{
System.out.println("method(long... x)");
}
public static void main(String[] args)
{
long x, y;
x = y = 0;
MyClass s = new MyClass();
s.method(x, y);
}
}
Результат method(Long x, Long y)
. Компилятор Java дает предпочтение соответствующей сигнатуре метода класса Wrapper, отличной от примитивного метода varargs.
public class MyClass
{
public void method(Double x, Double y)
{
System.out.println("method(Double x, (Double y)");
}
public void method(int x, int y)
{
System.out.println("method(int x, int y)");
}
public void method(long... x)
{
System.out.println("method(long... x)");
}
public static void main(String[] args)
{
long x, y;
x = y = 0;
MyClass s = new MyClass();
s.method(x, y);
}
}
Результат method(long ...x)
. Компилятор не будет сузить «длинное» примитивное значение до «int»; Кроме того, он не может долго затягивать Double Class. Можно использовать только метод var-args.
public class MyClass
{
public void method(Long x, Long y)
{
System.out.println("method(Long x, Long y)");
}
public static void main(String[] args)
{
int x, y;
x = y = 0;
MyClass s = new MyClass();
s.method(x, y);
}
}
Аргументы не могут быть «длинными», а затем «Long». Вы получите ошибку компиляции.
- Чтобы сохранить память, два экземпляра следующих объектов-оболочек всегда будут ==, когда их примитивные значения одинаковы. Пожалуйста, прочитайте, почему преобразование autoboxing иногда возвращает одну и ту же ссылку?
Непреднамеренный авто (un) бокс может быть высокопрофессиональным бором, если он выполняется в цикле, выполняемом много раз. Это может быть причиной того, что некоторые люди считают это злым. Тем не менее, настоящая проблема здесь - небрежное кодирование (и отсутствие профилирования), а не сама языковая функция. –
Если я использую дженерики, могу ли я избежать автобоксинга и распаковки? – John
@John Вы можете избежать ненужных автобоксинга и распаковки, тщательно изучив, использовать ли примитивный или обертковый тип и проверять, вызывает ли какой-либо вызов метод бокса. Однако, поскольку вам необходимо использовать тип обертки с дженериками, обычно нет способа избежать этого. – Carlos