Comprensión completa de los tipos básicos de tipos de datos de Java y los conceptos de tipos de referencia (recopilados en línea)

Tienes que sentarte y leer este artículo con atención . Después de leer este artículo en un día, creo que estás ganando dinero todo el día.

1. Primero, los tipos de datos de Java se clasifican como:

Todo debería ser un objeto en el mundo Java. ¿Por qué hay tipos básicos?

(1) Debido a problemas de rendimiento, tenemos que usar : Java basado en consideraciones de rendimiento, los tipos de datos básicos escritos en c , los tipos de datos básicos se almacenan en la pila (la velocidad de acceso es más rápida que el montón, solo superada por los registros ubicado directamente en la CPU ) relación de velocidad El almacenamiento dinámico es extremadamente rápido y las variables definidas por los tipos básicos se crean y destruyen rápidamente, mientras que las variables definidas por la clase deben ser destruidas por la JVM.
(2) Para cumplir con Java orientado a objetos : boxing y unboxing : el  tipo de empaquetado envuelve el valor del tipo básico en el objeto, de modo que pueda usar el método del objeto para manipular el tipo básico y la conversión entre tipos requiere el uso del método de tipo de embalaje. Se puede completar, por lo que se requiere el tipo de embalaje.

Boxeo : el proceso de convertir tipos básicos en clases de empaque.

Unboxing : el proceso de convertir clases de empaque en tipos básicos

  (3) [La diferencia entre objeto y tipo de datos básicos]

Los tipos de datos básicos se asignan en la pila y los tipos de objeto se asignan en el montón.

Los parámetros de todos los métodos se pasan por referencia en lugar de su propio valor (excepto los tipos básicos).

La asignación entre objetos es solo pasar por referencia, la asignación entre tipos básicos es crear una nueva copia.

2. Ocho tipos básicos

Los ocho tipos básicos en Java son: byte, short, int, long, float, double, char y boolean.

Permítanme comenzar con la primera pregunta:

(1). Problema de desbordamiento de datos de conversión de tipos

Primero: 1 byte ocupa 8 bits.

Dividido en las siguientes categorías:

      Tipo entero: byte, short, int, long ocupan 1, 2, 4 y 8 bytes de espacio respectivamente;

      Tipo de coma flotante: long y float ocupan 4 y 8 bytes respectivamente;

      Tipo de char: char ocupa 2 bytes;

      tipo booleano: booleano ocupa 1 bit.

Es necesario intercalar un concepto entre ellos: +++++++ bytes y bits +++++++

Concepto de bits

En el sistema numérico binario, cada 0 o 1 es un bit, y un bit es la unidad más pequeña de almacenamiento de datos. Entre ellos, 8 bits se denomina byte (Byte). La cantidad de bits de CPU en una computadora se refiere a la cantidad máxima de bits que la CPU puede procesar a la vez. Por ejemplo, la CPU de una computadora de 32 bits puede procesar hasta 32 bits de datos a la vez.

Bits binarios:

El bit binario se abrevia como "bit", que es un símbolo que representa un número entero menor que 2 en el sistema numérico binario, generalmente se representa con 1 o 0, que es uno de dos estados con igual probabilidad.

El número de bits binarios puede representar la longitud de palabra de una palabra de máquina, y la cantidad de información contenida en un bit binario se denomina bit

Bit (BIT, sistema binario):

La terminología informática es una unidad de información, que se transcribe del inglés BIT. Al mismo tiempo, también es el bit en el número binario, la unidad de medida de la cantidad de información y la unidad más pequeña de la cantidad de información. Información necesaria para reducir a la mitad el número de estímulos alternativos cuando es necesario realizar distintas elecciones. Es decir, la cantidad de información (número de bits) de la señal es igual al logaritmo del estímulo de la señal con 2 como base. L. Hartley pensó en 1928 que la unidad logarítmica es la medida más apropiada para la cantidad de información. Por ejemplo, el número binario 0100 es de 4 bits.

Problemas de expansión:

(1) ¿Por qué debería uno diseñar 1 byte = 8Bit?

El llamado byte, la intención original se utiliza para representar un carácter completo. El rendimiento inicial de la computadora y la capacidad de almacenamiento eran relativamente pobres, por lo que generalmente se usó la codificación BCD de 4 bits (esta codificación apareció antes que las computadoras y se usó por primera vez en tarjetas perforadas). El código BCD está bien para representar números, pero no es fácil representar letras o símbolos, y se necesitan varios códigos para representarlo. Más tarde evolucionó el código BCD de 6 bits (BCDIC) y el código ASCII de 7 bits que todavía se usa ampliamente en la actualidad. Pero es el famoso System / 360 el que determina el tamaño del byte al final. En ese momento, IBM diseñó un conjunto de códigos EBCDIC de 8 bits para System / 360, que cubría números, letras mayúsculas y minúsculas y los símbolos más comunes, y era compatible con códigos BCDIC de 6 bits ampliamente utilizados en tarjetas perforadas. System / 360 tuvo mucho éxito y sentó las bases para la longitud de 8 bits de la unidad de almacenamiento de caracteres. Este es el origen de 1 byte = 8 bits.

Enlaces a las siguientes dos preguntas: https://www.jianshu.com/p/d0a8ff006f5c

(2) Todos sabemos que el valor máximo que puede representar un binario de 8 bits es 1111 1111 == 255, pero ¿por qué el valor máximo es 127?

Porque para las computadoras, el bit más alto de un número binario es el bit de signo, donde 0 representa un número positivo y 1 representa un número negativo.
Entonces 1111 1111 significa -127, y 0111 1111 significa 127, el rango debe estar entre [-127,127]

(3) Todos sabemos que el rango de números que puede expresar un Byte es [-128,127], entonces, ¿de dónde viene este -128?

Esto involucra el código original, el código inverso y el complemento del conocimiento relevante, aquí hay una pequeña expansión, quiero entender más claramente, puedes aprender más.

Antecedentes: El código original, el código inverso y el código de complemento se generan para resolver el problema de la computadora haciendo la resta e introduciendo bits de signo (signos positivos y negativos).

Enlace relacionado: https://blog.csdn.net/zhiwen_a/article/details/81192087

+++++++ Byte y final de bit +++++++

Después de conocer la relación entre bytes y marcadores de posición, continúe hablando sobre el problema del desbordamiento del valor de conversión de tipo:

Debido a que el número de bits de almacenamiento es diferente, el rango de valores almacenados en diferentes tipos básicos es diferente

Cuando se realiza una conversión de tipo, el tamaño del espacio de bytes utilizado por el tipo es diferente , por lo que la conversión ascendente: la conversión implícita se puede realizar directamente, la conversión descendente y el desbordamiento de datos puede ocurrir . La lógica de conversión es la siguiente:

å¨è¿éæå ¥ å¾çæè¿ °

Para obtener detalles de la lógica de conversión, consulte esto: https://blog.csdn.net/weixin_44736274/article/details/90769042

Para ver el ejemplo de demostración de prueba de conversión de Java específico, consulte esto: https://blog.csdn.net/jreffchen/article/details/81015884

(2). El problema de pasar por valor o por referencia

(1) Creación de tipos básicos: Al declarar e inicializar variables locales de tipos de datos básicos, los nombres de las variables y los valores literales se almacenan en la pila y son el contenido real.

Proceso específico: como int age = 50;

Primero, JVM crea una variable llamada edad y la almacena en la tabla de variables locales, luego va a la pila para averiguar si hay un contenido con un valor literal de 50. Si lo hay, apunta directamente la edad a esta dirección. Si no es así, la JVM estará en la pila. Abra un espacio para almacenar el contenido de "50" y apunte la edad a esta dirección. Por lo tanto, podemos saber que cuando
declaramos e inicializamos variables locales de tipos de datos básicos, los nombres de las variables y los valores literales se almacenan en la pila y son el contenido real.

640? Wx_fmt = png

(2) La creación de tipos de referencia: tipos de datos de referencia de objetos / matrices, los nombres de las variables se almacenan en la pila y los valores de las variables almacenan la dirección del objeto, no el contenido real del objeto.

Proceso específico: como Persona p = nueva Persona ();

Al ejecutar Person per;, la JVM primero abre una parte de la memoria para almacenar la variable per en la tabla de variables en la pila de la máquina virtual. Al ejecutar per = new Person (), la JVM crea un objeto de instancia de la clase Person y abre una pieza en el montón. La memoria almacena esta instancia y, al mismo tiempo, asigna el valor de la dirección de la instancia a la variable per. Por lo tanto, se puede ver que
para objetos / matrices de tipos de datos de referencia, el nombre de la variable se almacena en la pila y el valor de la variable almacena la dirección del objeto, no el contenido real del objeto.

640? Wx_fmt = png

Enlaces relacionados detallados: https://mp.csdn.net/postedit/100006266

(3) Comprensión de la transferencia de valores y la transferencia de referencias.

Ambos pases pueden entenderse como una variable externa al llamar a un método, el método de operaciones internas no cambiará el valor de esta variable .

Use el código para hacer una demostración de todas las situaciones:

Tome int como ejemplo para el tipo básico:

En tipos básicos, en el método reasignado dentro de los parámetros y método de incremento, no afectará el valor de los parámetros externos .

public class IntPassByValue {
    public static void main(String[] args) {
        int a = 6;
        System.out.println("输出开始的值:" + a);
        changeIntValue(a);
        System.out.println("输出结束1的值:" + a);
        addIntValue(a);
        System.out.println("输出结束2的值:" + a);
    }

    /**
     *重新赋值
     */
    static void changeIntValue(int a) {
        a = 18;
        System.out.println("输出重新赋值方法中间的值:" + a);
    }

    /**
     *内容自增
     */
    static void addIntValue(int a) {
        a += 1;
        System.out.println("输出自增方法中间的值:" + a);
    }
}

Como resultado, las operaciones dentro del método llamado no afectarán los parámetros externos :

输出开始的值:6
输出重新赋值方法中间的值:18
输出结束1的值:6
输出自增方法中间的值:7
输出结束2的值:6

2. Tipo de referencia de clase

public class ClassPassByReference {
    public static void main(String[] args) {
        Student student = new Student(1, "张三");
        System.out.println("输出开始的值:" + student.toString());
        changeClassWholeValue(student);
        System.out.println("输出结束1的值:" + student.toString());
        changeClassLocalValue(student);
        System.out.println("输出结束2的值:" + student.toString());
    }

    /**
     *修改引用指向的地址
     */
    static void changeClassWholeValue(Student student) {
        student = new Student(2,"李四");
        System.out.println("输出重新赋值方法中间的值:" + student.toString());
    }

    /**
     *修改引用指向的地址对应的内容
     */ 
    static void changeClassLocalValue(Student student) {
        /*只修改name,不改id*/
        student.setName("王五");
        System.out.println("输出自增方法中间的值:" + student.toString());
    }
}

resultado:

输出开始的值:Student{id=1, name='张三'}
输出重新赋值方法中间的值:Student{id=2, name='李四'}
输出结束1的值:Student{id=1, name='张三'}
输出自增方法中间的值:Student{id=1, name='王五'}
输出结束2的值:Student{id=1, name='王五'}

Adjunte la clase del alumno:

public class Student {

    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

3. Tipo de referencia Clase de cadena

public class StringPassByReference {
    public static void main(String[] args) {
        String a = "最初1";
        System.out.println("输出开始的值:" + a);
        changeStringWholeValue(a);
        System.out.println("分割线+++++++string结束++++++++输出结束1的值:" + a);

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("stringBuilder开始");
        System.out.println("输出stringBuilder开始的值:" + stringBuilder);
        changeStringBuilderWholeValue(stringBuilder);
        System.out.println("输出stringBuilder修改1的值:" + stringBuilder);
        changStringBuilderLocalValue(stringBuilder);
        System.out.println("输出stringBuilder修改2的值:" + stringBuilder);
    }

    /**
     * 修改引用指向的地址
     */
    static void changeStringWholeValue(String a) {
        a = "修改1";
        System.out.println("输出重新赋值方法中间的值:" + a);
    }

    /**
     * 修改StringBuilder引用指向的地址
     */
    static void changeStringBuilderWholeValue(StringBuilder a) {
        StringBuilder changeStringBuilder = new StringBuilder();
        changeStringBuilder.append("修改指向引用地址");
        a = changeStringBuilder;
        System.out.println("输出修改StringBuilder引用指向的地址:" + a.toString());
    }

    /**
     * 修改StringBuilder引用指向的地址对应的内容
     */
    static void changStringBuilderLocalValue(StringBuilder a) {
        a.append("增加str");
        System.out.println("输出修改StringBuilder引用指向的地址对应的内容:" + a);
    }
}

Resultados: 1. Dado que String es una cadena fuente inmutable y se modifica con final, no importa cómo manipule la cadena, se genera una nueva dirección str y la operación de llamar al método no afectará los parámetros externos. 2. Si StringBuilder cambia el parámetro de referencia en el método, no afectará al parámetro externo. 3. StringBuilder utiliza la dirección de referencia actual en el método. La modificación del contenido de esta dirección afectará el contenido de los parámetros externos.

输出开始的值:最初1
输出重新赋值方法中间的值:修改1
分割线+++++++string结束++++++++输出结束1的值:最初1
输出stringBuilder开始的值:stringBuilder开始
输出修改StringBuilder引用指向的地址:修改指向引用地址
输出stringBuilder修改1的值:stringBuilder开始
输出修改StringBuilder引用指向的地址对应的内容:stringBuilder开始增加str
输出stringBuilder修改2的值:stringBuilder开始增加str

Resumen : 1. Parámetros formales y parámetros reales. Los parámetros externos son parámetros reales. Cuando se llama al método, los parámetros formales son nuevos parámetros de referencia en lugar de parámetros reales. (Obtenga más información por sí mismo) 2. Los tipos se dividen en tipos básicos y tipos de referencia. 3. El tipo básico es poner el contenido de la variable en la pila. Si necesita crear un nuevo contenido, debe crear una nueva variable. Si llama al método, el parámetro formal y el parámetro real son dos diferentes variables de referencia, por lo que el cambio de contenido no se afecta entre sí, por lo que los parámetros básicos de operación en el método llamado por el tipo no afectarán los parámetros reales externos. 4. La clase de tipo de referencia es crear una referencia en la pila, y la dirección apunta al contenido creado en el montón. El parámetro real representado por el parámetro formal del método de llamada de clase es la dirección de la clase. Si la dirección Si se cambia el parámetro formal, la realidad externa no se verá afectada La dirección y contenido de los participantes. Si el contenido de la dirección apuntada se modifica de acuerdo con los parámetros formales, el contenido de los parámetros reales externos se verá afectado. 5. El tipo de referencia tiene una Cadena. Dado que la cadena es un tipo final, no se puede cambiar la creación de una cadena (esto se puede entender en profundidad), por lo que cada vez que se modifica el parámetro formal se generará una nueva dirección y contenido el punto original no se modificará El contenido de la dirección.

Supongo que te gusta

Origin blog.csdn.net/Mint6/article/details/100006266
Recomendado
Clasificación