Referencias a objetos enteros en Java
No hay un puntero en Java, pero también hay conceptos de referencia. De lo que queremos hablar aquí es si Integer es el mismo objeto.
1. Veamos primero un pedazo de código:
public static void main (string [] args) {entero a1 = 100; Entero b1 = a1; // El otro también puede ser b1 = 100 campo campo = nulo; intente {campo = a1.getclass (). getDeclaredfield ("valor"); } Catch (nosuchfieldException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } Catch (SecurityException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } campo.setAccessible (verdadero); intente {field.set (a1, 5000); } Catch (ilegalArgumentException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } Catch (ilegalAccessException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } System.out.println ("b1 ="+b1); Entero C1 = 100; System.out.println ("c1 ="+c1); } resultado:
B1 = 5000
C1 = 5000
De lo anterior, antes que nada, quiero explicar algunas cosas aquí.
1) Para el entero, el número entero entre -128-127 se ha inicializado y colocado en IntegerCache. Si está lleno, el objeto se lo quitará.
2) ¿B1 = A1 es una asignación numérica o el mismo objeto? Esto se puede ver a partir de los resultados que B1 y A1 apuntan al mismo objeto, no el mismo valor numérico
3) C1 = 100 significa que para los valores entre -128-127, todos los objetos obtenidos de IntegerCache. Después de cambiar el objeto entero correspondiente a 100, se cambiará el empaque posterior de 100. Debido a que al obtener objetos en caché, se usa el índice de matriz, no se utilizan comparaciones numéricas.
Sin embargo, modificar este caché será más peligroso, así que no les importe. Quién sabe qué paquete o plataforma JAR, empacar un 100 yuanes, pero el resultado no es 100 yuanes, y se bloqueará en ese momento.
2. A través de la descripción anterior, ¿cuál es la respuesta si se cambia a esto?
public static void main (string [] args) {Integer a1 = 200; Entero b1 = a1; Campo campo = nulo; intente {campo = a1.getclass (). getDeclaredfield ("valor"); } Catch (nosuchfieldException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } Catch (SecurityException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } campo.setAccessible (verdadero); intente {field.set (a1, 5000); } Catch (ilegalArgumentException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } Catch (ilegalAccessException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } System.out.println ("b1 ="+b1); Entero C1 = 200; System.out.println ("c1 ="+c1); } 3. Luego cámbielo
public static void main (string [] args) {Integer a1 = new Integer (100); Entero b1 = a1; Campo campo = nulo; intente {campo = a1.getclass (). getDeclaredfield ("valor"); } Catch (nosuchfieldException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } Catch (SecurityException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } campo.setAccessible (verdadero); intente {field.set (a1, 5000); } Catch (ilegalArgumentException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } Catch (ilegalAccessException e) {// TODO Auto Generado Bloque E.PrintStackTrace (); } System.out.println ("b1 ="+b1); Entero C1 = 100; System.out.println ("c1 ="+c1); } ¿Cuál es la respuesta? Para nuevas operaciones, los objetos no están en caja, sino que se generan en el montón.
No es difícil de entender si comprende el boxeo, el almacenamiento en caché y la cita. Puedes probarlo tú mismo.
Primero obtengamos algunos conocimientos básicos
Correspondencia de tipos básicos y clases de envoltorio byte byte corto corto int entero largo largo flotador float doble doble carácter booleano booleano
La correspondencia entre los tipos de datos básicos en los ocho anteriores es solo int-> Integer Char-> carácter. Los dos cambios son significativos, y el resto solo está convirtiendo la primera letra en minúsculas.
Aprendamos sobre las nuevas características de JDK5: Embalaje automático y unboxing
Boxeo automático: Convertir los tipos básicos a los tipos de clase de envasado
Unboxing automático: convierta el tipo de clase de envoltorio en el tipo básico
clase pública demo_integer {public static void main (string [] args) {// antes de jdk1.5 int a = 100; Entero a1 = nuevo entero (a); // envuelve el tipo de datos básicos en un objeto, cuadro int b = a1.intvalue (); // Convierta el objeto al tipo de datos básico y unbox // después de jdk1.5 int x = 100; Entero x1 = x; // Cuadro automáticamente, convierta el tipo de datos básicos en un objeto int y = x1 + x; // Unbox automáticamente, convierta el objeto al tipo de datos básico}}Cosas a tener en cuenta
clase pública demo_integer {public static void main (string [] args) {integer a = null; int b = a + 100; // La capa inferior de unboxing automático llamará a a.intvalue (), a es nula y a lanzará naturalmente nullpointerexception system.out.println (b); }}Preguntas de entrevista
clase pública demo_integer {public static void main (string [] args) {Integer i1 = new Integer (97); Entero i2 = nuevo entero (97); System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("-------------"); Entero i3 = nuevo entero (197); Entero i4 = nuevo entero (197); System.out.println (i3 == i4); System.out.println (i3.equals (i4)); System.out.println ("----------------"); }}Salida: False Verdadero ----------------------------------
razón:
Nuevo es abrir el espacio en la memoria del montón, y el valor de la dirección de comparación natural (==) es falso.
Dado que entero reescribe el método igual, la salida igual es verdadera.
Puede sentir que es demasiado simple y no tiene contenido técnico, porque lo anterior no es el punto, mire el código a continuación
clase pública demo_integer {public static void main (string [] args) {integer i1 = 127; Entero i2 = 127; System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("--------------"); Entero i3 = 128; Entero i4 = 128; System.out.println (i3 == i4); System.out.println (i3.equals (i4)); System.out.println ("---------------"); }}Salida: True True ------------------------------------------
razón:
¿Por qué dos objetos cuando int es mayor que 127? ¿El número 127 se siente muy familiar?
-128 a 127 son el rango de valor de byte. Si está dentro de este rango de valores, el boxeo automático no creará un objeto nuevo y lo obtendrá desde el grupo constante
Si se excede el rango de valores de byte, se creará un nuevo objeto.
Empaque automáticamente la capa subyacente y llame al método ValueOf (), análisis de código fuente simple (JDK1.8):
El número entero de la clase final pública extiende los implementos comparables <integer> {public static entero valor de (int i) {// When i> = -128 e i <= 127, el objeto en el búfer se recuperará directamente si (i> = integerCache.low && i <= integerCache.high) return integercache.cache [i + (--intein return New entero (i); // Si el rango de valores de byte excede el rango, se creará en la memoria Heap} // La clase interna actúa como una clase estática privada de búfer IntegerCache {static final int low = -128; estático final int high; Cache entero final estático []; static {// El valor alto puede configurarse mediante la propiedad int h = 127; String IntegerCacheHighPropValue = Sun.Misc.Vm.GetSavedProperty ("java.lang.integer.integercache.high"); if (integerCacheHighPropValue! = null) {try {int i = parseInt (integerCacheHighPropValue); i = math.max (i, 127); // El tamaño máximo de la matriz es integer.max_value h = math.min (i, integer.max_value -(-low) -1); } Catch (NumberFormateException nfe) {// Si la propiedad no se puede analizar en un int, ignórelo. }} high = h; caché = nuevo entero [(alto - bajo) + 1]; int j = bajo; para (int k = 0; k <cache.length; k ++) caché [k] = nuevo entero (j ++); // El rango [-128, 127] debe ser internalizado (jls7 5.1.7) afirmar integercache.high> = 127; } private integerCache () {}}} 8 tipos básicos de clases de envoltura y piscinas de objetos
La mayoría de los tipos básicos de clases de envoltura en Java implementan tecnología de agrupación constante. Estas clases son byte, cortas, enteras, largas, carácter, booleanas y los otros dos tipos de clases de envoltorio con número de punto flotante no se implementan. Además, las cinco clases de envoltura entera de byte, cortas, enteros, largas, largas, solo pueden usar el grupo de objetos cuando el valor correspondiente es menor o igual a 127, es decir, el objeto no es responsable de crear y administrar objetos de estas clases superiores a 127.
Conocimiento extendido
En la especificación JVM, cada tipo tiene su propio grupo constante. Un grupo constante es una colección ordenada de constantes utilizadas por un determinado tipo, incluidas las constantes directas (tipos primitivos, cadenas) y referencias simbólicas a otros tipos, campos y métodos. La razón por la que es una referencia simbólica en lugar de especificar directamente otros tipos en el momento de la compilación es porque Java está dinámicamente unido, y solo en tiempo de ejecución puede las instancias de dependencia específicas de tipo se determinan de acuerdo con ciertas reglas. Esta es la base para que Java implemente el polimorfismo.
En el JVM, todo el ciclo de vida de una clase comienza desde cargarse en la memoria de la máquina virtual y hasta que se descarga fuera de la memoria. Todo su ciclo de vida incluye: carga, verificación, preparación, análisis, inicialización, uso y descarga. La etapa de análisis es el proceso de la máquina virtual que reemplaza las referencias de símbolos en el grupo constante con referencias directas.
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.