El problema automático de embalaje y unboxing es un problema común en Java. Hoy echaremos un vistazo a algunos de los problemas en el embalaje y la unboxing. Este artículo primero habla sobre las cosas más básicas sobre el embalaje y el desempaquetado, y luego analiza los problemas relacionados con el embalaje y el desempaquetado que a menudo se encuentran en la prueba escrita a continuación.
1. ¿Qué es empacar? ¿Qué es el unboxing?
En el artículo anterior, Java proporciona los tipos de envoltorio correspondientes para cada tipo de datos básicos. En cuanto a por qué se proporcionan los tipos de envoltura para cada tipo de datos básicos, no se explicará aquí. Los amigos interesados pueden consultar la información relevante. Antes de Java SE5, si desea generar un objeto entero con un valor de 10, debe hacer esto:
La copia del código es la siguiente:
Entero i = nuevo entero (10);
Desde Java SE5, se proporciona la función de boxeo automático. Si desea generar un objeto entero con un valor de 10, solo necesita hacer esto:
La copia del código es la siguiente:
Entero i = 10;
En este proceso, el objeto entero correspondiente se creará automáticamente en función del valor numérico, que está empaquetando.
Entonces, ¿qué es el unboxing? Como su nombre lo indica, corresponde al embalaje, que convierte automáticamente el tipo de envoltorio en el tipo de datos básicos:
La copia del código es la siguiente:
Entero i = 10; //embalaje
int n = i; // Unbox
En pocas palabras, el embalaje significa convertir automáticamente el tipo de datos básico al tipo de envoltorio; Unboxing significa convertir automáticamente el tipo de envoltorio al tipo de datos básico.
La siguiente tabla es el tipo de envoltura correspondiente al tipo de datos básico:
2. ¿Cómo se implementan el embalaje y el unboxing?
Después de comprender los conceptos básicos de embalaje en la sección anterior, esta sección comprenderá cómo se implementan el embalaje y el unboxing.
Tomemos la clase Interger como ejemplo y veamos un código a continuación:
Public Class Main {public static void main (string [] args) {integer i = 10; int n = i;}}Después de descomparar el archivo de clase, obtendrá el siguiente contenido:
Desde el contenido de Bytecode obtenido por descomposición, se puede ver que el método Value (int) de entero se llama automáticamente al empacar. Al desempaquetar, el método intValue de entero se llama automáticamente.
Otros son similares, como el doble o el carácter. Los amigos que no creen en él pueden probarlo manualmente por sí mismos.
Por lo tanto, el proceso de implementación de embalaje y unboxing se puede resumir en una oración:
El proceso de boxeo se implementa llamando al Método ValorOf de la envoltura, mientras que el proceso de Unboxing se implementa llamando al método XXXValue del envoltorio. (xxx representa el tipo de datos básicos correspondientes).
3. Preguntas relacionadas durante la entrevista
Aunque la mayoría de las personas tienen claro los conceptos de embalaje y unboxing, es posible que no puedan responder preguntas sobre el embalaje y el desempeño durante las entrevistas y las pruebas escritas. A continuación se muestran algunas preguntas comunes de entrevista relacionadas con el embalaje/unboxing.
1. ¿Cuál es el resultado de salida del siguiente código?
clase pública Main {public static void main (string [] args) {integer i1 = 100; integer i2 = 100; integer i3 = 200; integer i4 = 200; system.out.println (i1 == i2); System.out.println (i3 == i4);}} Tal vez algunos amigos digan que producirán falsos, o algunos amigos dirán que producirán verdadero. Pero de hecho la salida es:
verdadero
FALSO
¿Por qué ocurre tal resultado? Los resultados de la salida muestran que I1 e I2 apuntan al mismo objeto, mientras que I3 e I4 apuntan a diferentes objetos. En este punto, solo necesita mirar el código fuente para conocer la verdad. El siguiente código es la implementación específica del método Value de Integer:
public static static entero de (int i) {if (i> = -128 && i <= integerCache.high) return integerCache.cache [i + 128]; Elsereturn new entero (i);} La implementación de la clase IntegerCache es:
Clase estática privada IntegerCache {static final int high; static final entero caché []; static {final int low = -128; // El valor alto puede estar configurado por PropertyInt h = 127; if (IntegerCacheHighHighPropvalue! = NULL) {// Use largo. Decode aquí para evitar invocar los métodos que // requerir inicio de integer a ser inicializando que sea inicializando a ser inicializando a ser inicialmente para ser inicializado a ser inicializado a ser inicialmente inicial para ser inicializando a ser inicializado para ser inicializado a ser inicializante para ser inicializado a ser inicializante para ser inicializado a ser inicial. Long.Decode (InteGerCacheHighPropvalue) .IntValue (); i = Math.max (i, 127); // El tamaño máximo de la matriz es Integer.max_valueh = Math.min (i, Integer.max_value - -low);} High = H; cache = newger [(alto - low); k <cache.length; De estas dos piezas de código, al crear un objeto entero a través del método ValueOf, si el valor es entre [-128, 127], se devuelve una referencia al objeto que ya existe en IntegerCache.cache; De lo contrario, se crea un nuevo objeto entero.
En el código anterior, los valores de I1 e I2 son 100, por lo que los objetos existentes se tomarán directamente del caché, por lo que I1 e I2 apuntan al mismo objeto, mientras que I3 e I4 apuntan a diferentes objetos respectivamente.
2. ¿Cuál es el resultado de salida del siguiente código?
clase pública Main {public static void main (string [] args) {double i1 = 100.0; double i2 = 100.0; double i3 = 200.0; double i4 = 200.0; system.out.println (i1 == i2); system.out.println (i3 == i4);}} Tal vez algunos amigos piensen que el resultado de la salida es el mismo que la pregunta anterior, pero de hecho no lo es. La salida real es:
FALSO
FALSO
En cuanto a la razón específica, los lectores pueden verificar la implementación del valor de la clase doble.
Aquí solo explicaré por qué el valor del método de la clase doble adopta una implementación diferente que el valor del método de la clase entera. Es muy simple: el número de valores enteros en un rango determinado es finito, pero los números de puntos flotantes no lo son.
Tenga en cuenta que la implementación de valores de métodos de entero, corto, byte, carácter y largo es similar.
La implementación del Método Value de Double y Float es similar.
3. ¿Cuál es el resultado de salida del siguiente código:
clase pública Main {public static void main (string [] args) {boolean i1 = false; boolean i2 = false; boolean i3 = true; boolean i4 = true; system.out.println (i1 == i2); system.out.println (i3 == i4);}} El resultado de la salida es:
verdadero
verdadero
En cuanto a por qué este es el resultado, también será claro de un vistazo después de leer el código fuente de la clase booleana. La siguiente es la implementación específica del método Value de Boolean:
Public static boolean valorof (booleano b) {return (b? verdadero: falso);} ¿Y qué son verdaderos y falsos? 2 Las propiedades de los miembros estáticos se definen en Boolean:
public static final boolean true = new Boolean (true);/** * El objeto <code> boolean </code> correspondiente al primitivo * valor <code> false </code>. */public static final boolean false = new Boolean (falso);
En este punto, todos deben entender por qué la salida anterior es verdadera.
4. Hable sobre la diferencia entre el número entero i = nuevo entero (xxx) e integer i = xxx;
Por supuesto, este tema pertenece a un tipo relativamente amplio. Pero los puntos clave deben ser respondidos. Permítanme resumir las siguientes dos diferencias:
1) El primer método no activará el proceso de boxeo automático; mientras que el segundo método se activará;
2) La diferencia en la eficiencia de ejecución y la utilización de recursos. El segundo método de eficiencia de ejecución y uso de recursos es mejor que el primero en general (tenga en cuenta que esto no es absoluto).
5. ¿Cuál es el resultado de salida del siguiente programa?
clase pública Main {public static void main (string [] args) {integer a = 1; entero b = 2; entero c = 3; entero d = 3; entero e = 321; entero f = 321; largo g = 3l; largo H = 2l; system.out.println (c == d); system.out.println (e == f); system.out.println (c == (a+b)); system.out.println (c.equals (a+b)); system.out.println (g == (a+b)); system.out.println (g.equals (a+h); No mire primero los resultados de la salida, los lectores pensarán en los resultados de la salida de este código para ellos mismos. Lo que debe tenerse en cuenta aquí es que cuando los dos operandos del operador "==" son referencias al tipo de envoltorio, compara si el puntero es el mismo objeto, y si uno de los operandos es una expresión (es decir, contiene operaciones aritméticas), compara los valores numéricos (que activará el proceso de descripción automática). Además, para los tipos de envoltorio, el método igual no realiza la conversión de tipo. Después de comprender estos 2 puntos, los resultados de salida anteriores serán claros de un vistazo:
verdadero
FALSO
verdadero
verdadero
verdadero
FALSO
verdadero
No hay duda sobre los resultados de la primera y segunda salida. En la tercera oración, dado que A+B contiene operaciones aritméticas, desencadena el proceso automático de unboxing (se llamará al método intValue), por lo que comparan si los valores son iguales. Para C.Equals (A+B), el proceso automático de desempaquetado se activará primero, y luego se activará el proceso de embalaje automático. Es decir, A+B, cada uno llamará al método intValue, y después de obtener el valor después de la operación de adición, se llamará al método Integer.ValueOf, y luego se realizará la comparación igual. Lo mismo es cierto para lo siguiente, pero preste atención a los resultados del segundo a la última y última salida (si el valor es de tipo int, el proceso de boxeo llama a integer.valueOf; si es de tipo largo, el método de boxeo llama largo.valueOf).
Lo anterior es una comprensión profunda del embalaje y el unboxing en Java presentados por el editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!