Java Foundation en Android (2) - Boxing y Unboxing y comparación de diferentes tipos básicos (conversión de tipos)

Ya sea en Android o Java, encontraremos tipos de datos básicos y operaciones de conversión correspondientes a tipos de datos de referencia, etc. Aquí, el análisis de instancias se realiza mediante operaciones de boxing y unboxing y conversión de tipos.

Boxing y unboxing aparecieron en jdk 1.5 y superior, donde

Boxing se refiere a la conversión de una instancia de tipo de valor en un objeto en programación, lo que implica que la instancia llevará información de tipo completa en tiempo de ejecución y se asignará en el montón.

Unboxing es la conversión de un tipo de referencia a un tipo de valor. Usando las funciones de boxing y unboxing, un tipo de valor se puede vincular a un tipo de referencia al permitir que cualquier valor del tipo de valor se convierta a y desde un tipo de objeto.

Al explicar la paráfrasis, podemos entender

Entero a = 1;

Esta es una operación de boxeo, que crea automáticamente un objeto Integer y apunta a este objeto.

int a = nuevo entero (1);

Al contrario de la operación boxing, cree un objeto Integer con un valor de 1, mientras convierte el tipo Integer al tipo primitivo int,

Podemos entenderlo así: trate la "caja" como un contenedor, en el que 1 es un valor, agregue el valor 1 al contenedor y el objeto formado es un encajonamiento. La operación de quitar el contenedor y sacar el 1 es llamado desempaquetado. ,

Para Integer\int, el proceso de boxing es llamar al método valueOf del tipo correspondiente, y el proceso de unboxing es llamar al método intValue() de la clase correspondiente. Los siguientes tipos tienen operaciones de boxing y unboxing:

 Por ejemplo, la función valueOf en Integer


public static Integer valueOf(int i) {
        return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
    }
 
    /**
     * A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing
     */
    private static final Integer[] SMALL_VALUES = new Integer[256];
 
    static {
        for (int i = -128; i < 128; i++) {
            SMALL_VALUES[i + 128] = new Integer(i);
        }
    }

Función valor int

 @Override
    public int intValue() {
        return value;
    }

De acuerdo con las operaciones mencionadas anteriormente, podemos saber que las operaciones de boxing y unboxing se activan por asignación, pero ¿cómo activarlo de otras maneras? Analizamos uno por uno de acuerdo con algunos de los problemas básicos comunes de Java actuales.

 int mint127 = new Integer(127);//拆箱操作
        int mint1 = 1;
        Integer mInteger127a = 127; //装箱操作
        Integer mInteger127b = 127;//装箱操作
        int mint128 = 128;
        Integer mNewInteger127a = new Integer(127);
        Integer mNewInteger128b = new Integer(128);
        Integer mInteger128a = 128;//装箱操作
        Integer mInteger128b = 128;//装箱操作
        Long mLong127 = 127L;//装箱操作
        Long mLong128 = 128L;//装箱操作
        Short mShort127 = 127;
        short mshort1 = 1;
        byte mbyte1 = 1;
        byte mByte1 = new Byte((byte)1);;
 
        Byte mByte127 = new Byte((byte)127);
        Byte  mResult= (byte) (mByte1+mByte127);//先拆箱相加,由于+操作会将变量转成int,只能强制转为byte,导致超范围,数据损失
 
        System.out.println("mint127 == mInteger127a -->"+(mint127 == mInteger127a));
        System.out.println("mInteger127a== mInteger127b -->"+(mInteger127a== mInteger127b));
        System.out.println("mInteger128a== mInteger128b -->"+(mInteger128a== mInteger128b));
        System.out.println("(mInteger127a+mint1)== mNewInteger128b -->"+((mInteger127a+mint1)== mNewInteger128b));
        System.out.println("(mLong127+mint1)== mNewInteger128b -->"+((mLong127+mint1)== mNewInteger128b))
        ;
        System.out.println("(mLong128.equals(mLong127+mint1)) -->"+(mLong128.equals(mLong127+mint1)));
        System.out.println("(mLong128==(mLong127+mint1)) -->"+(mLong128==(mLong127+mint1)));
        System.out.println("(mNewInteger128b.equals(mLong127+mint1)) -->"+(mNewInteger128b.equals(mLong127+mint1)));
        System.out.println("(mNewInteger128b==(mLong127+mint1)) -->"+(mNewInteger128b==(mLong127+mint1)));
        System.out.println("(mNewInteger128b.equals(mShort127+mint1)) -->"+(mNewInteger128b.equals(mShort127+mint1)));
        System.out.println("(mNewInteger128b==(mShort127+mint1)) -->"+(mNewInteger128b==(mShort127+mint1)));
        
        System.out.println("(mNewInteger128b==(mShort127+mshort1)) -->"+(mNewInteger128b==(mShort127+mshort1)));
        System.out.println("(mNewInteger128b==(mByte127+mbyte1)) -->"+(mNewInteger128b==(mByte127+mByte1)));
        System.out.println("(byte) (mByte1+mByte127) -->"+mResult);

El siguiente es el resultado de ejecución:


mint127 == mInteger127a -->true //mInteger127a使用intValue() 拆箱操作
mInteger127a== mInteger127b -->true //地址相同,在-128到127范围内
mInteger128a== mInteger128b -->false //地址不同,通过valueOf()函数new的两个对象
(mInteger127a+mint1)== mNewInteger128b -->true //可以理解只要有int等基本类型,在加减或者比较操作中都需要拆箱然后处理,例如mint1
(mLong127+mint1)== mNewInteger128b -->true //拆箱比较
(mLong128.equals(mLong127+mint1)) -->true //拆箱,比值
(mLong128==(mLong127+mint1)) -->true //拆箱,比值。问题1,见下解释
(mNewInteger128b.equals(mLong127+mint1)) -->false //问题2,因为mLong127拆箱成long,总体转化为long型,equals比较返回false,见下解释
(mNewInteger128b==(mLong127+mint1)) -->true //拆箱比值
(mNewInteger128b.equals(mShort127+mint1)) -->true //问题3,拆箱,比值,见下解释
(mNewInteger128b==(mShort127+mint1)) -->true //拆箱,比值
(mNewInteger128b==(mShort127+mshort1)) -->true  //拆箱,比值
(mNewInteger128b==(mByte127+mbyte1)) -->true //拆箱,比值
(byte) (mByte1+mByte127) -->-128 //因为mByte1拆箱为1,mByte127为127,这时候相加,自动转换为int型,结果128,超出byte范围,强制转为byte经过计算补码1000 0000为-128

Hay tantas preguntas arriba, vamos a explicarlas una por una, primero observe un conocimiento básico, escriba conversión

Conversión de tipos implícita:
para implementar la conversión de tipos implícita, se deben cumplir dos condiciones. Los dos primeros tipos son compatibles entre sí y el rango de 
valores debe ser mayor que el tipo de origen. Todos los tipos numéricos, incluidos los números enteros y los flotantes, se pueden convertir entre sí.

La dirección de conversión es:

 

Nota: Para los operadores binarios (incluidos los operadores de comparación), si un operando es de tipo float, double o long, el otro operando se convierte en float, double o long; de lo contrario, ambos operandos se convierten en tipo int (es decir, byte, short , char se promoverá automáticamente a int).

La pregunta 1 se puede explicar (mLong128==(mLong127+mint1)) --> cierto, ambos lados se convierten en una comparación de tipo largo. tan verdadero,

Entonces, ¿por qué el resultado de la pregunta 2 (mNewInteger128b.equals(mLong127+mint1)) --> false y question (mNewInteger128b.equals(mShort127+mint1)) --> true es diferente? En la pregunta 2, mLong127+mint1 es un largo escriba al final En la pregunta 3, mShort127+mint1 es de tipo int, podemos ver la función equals,

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

Podemos encontrar que solo funciona el tipo Integer. Sabemos que en jdk1.5 y superior, int se puede convertir en un objeto Integer mediante el boxeo. Si no es un tipo int, no se puede usar. Esto también explica por qué el resultado de la pregunta 2 es falso. mLong127+mint1 es un tipo largo al final, y no puede ser juzgado como un tipo entero por instancia de.
Podemos observar qué tipo se pasa a través de la siguiente función testObject


public static String testObject(Object obj) {
        if (obj instanceof Integer) {
			return "Integer";
        }else if  (obj instanceof Long){
			return "Long";
		}else if  (obj instanceof Short){
			return "Short";
		}else if  (obj instanceof Float){
			return "Float";
		}else if  (obj instanceof Double){
			return "Double";
		}else if  (obj instanceof Boolean){
			return "Boolean";
		}else if  (obj instanceof Byte){
			return "Byte";
		}else if  (obj instanceof Character){
			return "Character";
		}
        return "wrong type";
    }

P.ej

System.out.println("(byte)1+(char)1-->"+testObject((byte)1+(char)1));
System.out.println("(int)1+(char)1-->"+testObject((int)1+(char)1));
System.out.println("(int)1+(float)1-->"+testObject((int)1+(float)1));
System.out.println("(long)1+(float)1-->"+testObject((long)1+(float)1));

El resultado es el siguiente

(byte)1+(char)1-->Integer 
(int)1+(char)1-->Integer
(int)1+(float)1-->Float
(long)1+(float)1-->Float

Coerción tipo conversión: (expresión) Su función es coaccionar el resultado de la operación de la expresión al tipo indicado por el especificador de tipo.
Al mismo tiempo, es necesario prestar atención a la posibilidad de pérdida de precisión e incluso error de datos al convertir de un rango grande a un rango pequeño al realizar la conversión de tipo obligatoria de tipos básicos. También tenga en cuenta los operadores de asignación como +=.

Por ejemplo: para abreviar a = 1; a= a+ 1; dado que el tipo de la expresión se promoverá automáticamente durante la operación a+1, el resultado es un tipo int, y cuando se asigna a un tipo abreviado a, el el compilador informará que el tipo debe ser emitido. 
Para abreviar a= 1; a += 1; dado que += es un operador especificado por el lenguaje java, el compilador java lo tratará de manera especial, para que pueda compilarse correctamente.

Supongo que te gusta

Origin blog.csdn.net/ahou2468/article/details/122243978
Recomendado
Clasificación