¿Realmente entender Java en el largo Bien?

El desarrollo actual, se utilizan los tipos largos de situaciones debe ser mucho. Pero, realmente comprender plenamente lo largo tipo?

código de ensayo

En primer lugar, nos fijamos en un código de prueba. Este código puede ser probado.

    @Test
    public void testLong() {
        long primaryLong = 127L;
        Long long1 = Long.valueOf(primaryLong);
        Long long2 = 127L;

        Assert.assertTrue(long1 == long2); // 1

        long1 = new Long(127L);
        Assert.assertFalse(long1 == long2); // 2

        primaryLong = 128L;
        long1 = Long.valueOf(primaryLong);
        long2 = 128L;

        Assert.assertFalse(long1 == long2);  // 3

        long1 = new Long(128L);
        Assert.assertFalse(long1 == long2);  // 4
    }
复制代码

En el código de prueba anterior, se compara la igualdad entre los dos tipos de variables LONG1 largo y Long2, aquí usamos el operador "==", la dirección utiliza para probar dos referencias a variables son iguales.

los agricultores de código de alto nivel deberían haber creado una larga Existen tres maneras: nueva largas (más), Long.valueOf () y envasadoras automáticas. El código muestra los resultados se obtuvieron de tres maneras.

  • código de análisis Nota 1 vuelve a la verdadera. Esto demuestra que cuando se utiliza el valor 127L, independientemente Long.valueOf largo asignación de variables para crear o uso autoboxing tiempo en un tipo largo, dos variables apuntan a la misma ubicación.
  • Análisis de código Nota 2 vuelve falsa. Esto demuestra que el uso de nueva creación a partir de Long (127L) variable larga, con sólo el uso de envasado automático creado variables de largo punto ya no en la misma ubicación.
  • Análisis 3,4 Nota código vuelve a falso. Esto muestra el valor de uso 128L crean variables de largo, cada una apuntando a una ubicación diferente, si es nuevo largo, Long.valueOf o envasado automático.

¿Cómo se va? Especialmente para Long.valueOf o envasado automática de estos dos métodos, en realidad es de 127L y 128L cuando el resultado no es lo mismo?

Con el fin de entender completamente por qué el código anterior es tal resultado una, tuvimos que empezar desde el código fuente.

análisis

Nos java.lang.Long código fuente abierto. En el que el código de la llave es el siguiente.

public final class Long extends Number implements Comparable<Long> {
    private final long value; // 1

    private static class LongCache { // 2
        private LongCache(){} // 2.1

        static final Long cache[] = new Long[-(-128) + 127 + 1]; // 2.2

        static { // 2.3
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

    @Deprecated(since="9")
    public Long(long value) { // 3
        this.value = value;
    }

    @Deprecated(since="9")
    public Long(String s) throws NumberFormatException { // 4
        this.value = parseLong(s, 10);
    }

    public static Long valueOf(long l) { // 5
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
}
复制代码
  • Número de largo hereda de la clase de la clase base, una clase abstracta es un número de clase, el número de representantes. La siguiente figura muestra el Entero, Largo, Byte, Short, flotado y hereda doble de Número.

    Sólo algún tipo de métodos abstracta XXXValue. Como se muestra en la figura.

  • El análisis de largo Nota 1 representa una realidad interna o almacenar un valor variable para almacenar el tipo de datos original largo.

  • análisis Nota es 3,4 largo de dos método de construcción, dos métodos son de asignación de valor, ningún otro procesamiento.

  • Buscamos Análisis Nota 2 y 5: Análisis Nota 2 es una LongCache clase estática interna, a juzgar por el nombre, la clase debe ser una larga tipos de almacenamiento en caché:

    • El análisis indica la nota 2.1 LongCache un constructor privado, para evitar que las instancias de esa clase. constructor privada se utiliza típicamente en herramientas o clase de instancia única, por ejemplo común de realización de modo único requiere constructor privado.
    • 2.2 Análisis de clase NOTA expresada tiene una matriz de caché largo, y con la modificación static final. El tamaño de la matriz -(-128) + 127 + 1=256.
      La matriz final con un inicializado no se puede volver a asignar, pero todavía se puede modificar el valor de referencia de cada elemento de la matriz para almacenar en caché el próximo objetivo.
    • 2.3 Análisis de caché expresado Nota inicializado. 0-256 subíndices se inicializan a un valor entre -128 y 128.
  • A continuación, el análisis véase la nota 5, cuando el parámetro l es un valor entre -128 y 127, devuelve el valor de la matriz de memoria caché interna directa LongCache correspondiente al subíndice. Aquí, el desplazamiento se establece muy inteligente 128, estableciendo así el valor del índice mínimo es -128 (int) l + offset = 0. Que no es de [-128, 127] alcance de tales valores, los nuevos rendimientos llamada larga.

  • Al mismo tiempo, prestar atención al método de construcción de la @Deprecated(since="9")anotación que indica JDK9 desde el principio, el constructor no ha sido recomendado. documentación del JDK, se recomienda utilizar un método de fábrica estática para construir Long.valueOf largo objeto que se puede obtener un mejor rendimiento de espacio y tiempo.

De acuerdo con la gramática estándar, envasado automático llama en realidad es Long.valueOf, en lugar del constructor.

El análisis anterior, el valor de [-128, 127], ya sea o el uso de embalaje Long.valueOf automáticamente, son sujetos en última instancia para leer el valor LongCache.cache con ella, y por lo tanto "==" es cierto. Otros casos, 2 de cada variable diferente "==" comparación es falsa.

expandir

  • Para los métodos de la clase ShortCache ValueOf corto, y el código fuente de la clase e implementar un largo idénticos. Aquí no se lleva a cabo.
  • Para la clase Byte, sólo para recibir un valor entre 127 -128. valueOf método puede devolver todos los valores ShortCache.cache.
  • Para flotado y clases de matrimonio, sin el llamado FloatCache y DoubleCache, por lo que cada vez que se construye un nuevo objeto.
  • Con el fin de evitar diferencias de resultado "==" que aparece en el aparece comparación código de seguridad. Comparación entre la recomendación objeto, uso o es igual al tipo original de la reutilización de envases extraíble "==" comparación, el código de prueba anterior se puede utilizar long1.longValue () o la larga + LONG1 convierte a continuación en largo utilización "==" comparación

Nota, + LONG1 debe asegurar que el LONG1 + no vuelve nula. Si no, se informó NullPointerException.


Aquí una pequeña prueba para ver cómo entendemos?

Long long1 = new Long(100L);
Long long2 = 100L;
Long long3 = 100L;
Long long4 = 128L;
Long long5 = 128L;

System.out.println(long1 == long2);
System.out.println(+long1 == long2);

System.out.println(long2 == long3);
System.out.println(+long2 == long3);

System.out.println(long4 == long5);
System.out.println(+long4 == long5);
复制代码

¿Qué opinas de la salida del código anterior?

respuesta

false
true
true
true
false
true
复制代码

Supongo que te gusta

Origin juejin.im/post/5e6ada0fe51d45271849f498
Recomendado
Clasificación