Dentro de Java 5.0, clases de contenedor se han convertido en más fácil de usar. Java 5.0 introdujo la conversión automática entre un tipo primitivo y la clase contenedora correspondiente.
De tipo primitivo a la clase corresponsal de la clase se llama autoboxing, el proceso inverso se llama unboxing. Autoboxing y unboxing también se aplican a llamadas a métodos. Por ejemplo, puede pasar un argumento de tipo int a un método que tiene un parámetro formal de tipo Integer.
Se produce una excepción de excepción de Nullpointer Al desempaquetar una referencia de clase de envoltura nula a su tipo primitivo. Por ejemplo, el código se compilará pero emitirá una NullpointerException en tiempo de ejecución.
Long L = null; long l = L; ...
conversión Boxing convierte los valores de tipo primitivo a valores de tipo de referencia correspondiente. Pero los tipos primitivos no se pueden ensanchar/Estrechar a las clases de Contenedor y viceversa. Por ejemplo,
byte b = 43; Entero I1 = 23; // Valor entero constante Entero I2 = (int) b; // Cast para el tipo int Long L1 = 23; // error de compilación porque 23 es un valor entero Largo L2 = (Largo) 23; // no se puede convertir el valor entero a la clase Long wrapper Long L3 = 23L; Largo L4 = (largo) 23;
Esta restricción se aplica también a la invocación de métodos:
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);
}
}
El resultado es method(long x, long y)
. El compilador de Java comprobará los tipos primitivos coincidentes, luego buscará los tipos de Contenedor.
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);
}
}
El resultado es method(Long x, Long y)
. El compilador de Java da preferencia a la firma del método de clase Wrapper coincidente que no sea el método varargs primitivo.
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);
}
}
El resultado es method(long ...x)
. El compilador no reducirá el valor primitivo "largo" a "int"; Además, no puede ganar mucho tiempo para la clase Doble. Solo se puede usar el método 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);
}
}
Los argumentos no pueden winden a "long" y luego a "Long". Obtendrás un error de compilación.
- Para ahorrar memoria, dos instancias de los siguientes objetos contenedoras siempre serán == cuando sus valores primitivos sean los mismos. Por favor, lea ¿Por qué la conversión de autoboxing a veces devuelve la misma referencia?
El auto (des) boxeo involuntario puede ser un rendimiento alto, si se realiza en un bucle ejecutado muchas veces. Esta podría ser la razón por la cual algunas personas lo consideran malvado. Sin embargo, el verdadero problema aquí es la codificación descuidada (y la falta de creación de perfiles), en lugar de la característica del idioma en sí. –
Si uso genéricos, ¿puedo evitar autoboxing y unboxing? – John
@John Puede evitar el autoboxing y el desempaquetado innecesarios al considerar cuidadosamente si se debe usar el tipo de primitiva o de envoltura y verificar si hay alguna llamada a métodos que provoquemos el boxeo. Sin embargo, dado que necesitas usar el tipo de envoltorio con genéricos, generalmente no hay forma de evitarlo por completo. – Carlos