Java Foundation in Android (2) - Boxing and Unboxing and Comparison of Different Basic Types (Type Conversion)

Whether in Android or Java, we will encounter basic data types and conversion operations corresponding to reference data types, etc. Here, instance analysis is performed through boxing and unboxing operations and type conversion.

Boxing and unboxing appeared in jdk 1.5 and above, where

Boxing refers to the conversion of a value type instance to an object in programming, which implies that the instance will carry complete type information at runtime and be allocated in the heap.

Unboxing is the conversion of a reference type to a value type. Using the boxing and unboxing functions, a value type can be linked to a reference type by allowing any value of the value type to be converted to and from an Object type.

By explaining paraphrasing, we can understand

Integer a = 1;

This is a boxing operation, which automatically creates an Integer object, and a points to this object.

int a = new Integer(1);

Contrary to the boxing operation, create an Integer object with a value of 1, while converting the Integer type to the int primitive type,

We can understand it like this: treat the "box" as a container, in which 1 is a value, add the value 1 to the container, and the formed object is boxing. The operation of removing the container and taking out the 1 is called unboxing. ,

For Integer\int, the process of boxing is to call the valueOf method of the corresponding type, and the process of unboxing is to call the intValue() method of the corresponding class. The following types have boxing and unboxing operations:

 For example, the valueOf function in 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);
        }
    }

intValue function

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

According to the operations mentioned above, we can know that the boxing and unboxing operations are triggered by assignment, but how to trigger it in other ways? We analyze one by one according to some of the current common java basic problems.

 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);

The following is the running result:


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

There are so many questions above, let's explain them one by one, first look at a basic knowledge, type conversion

Implicit type conversion:
To implement implicit type conversion, two conditions need to be met. The first two types are compatible with each other, and the 
value must be greater than the source type. All numeric types, including integers and floats, are convertible to each other.

The conversion direction is:

 

Note: For binary operators (including comparison operators), if one operand is of type float, double or long, the other operand is converted to float, double or long, otherwise both operands are converted For int type (that is, byte, short, char will be automatically promoted to int).

Question 1 can be explained (mLong128==(mLong127+mint1)) --> true, both sides are converted to long type comparison. so true,

So why is the result of question 2 (mNewInteger128b.equals(mLong127+mint1)) --> false and question (mNewInteger128b.equals(mShort127+mint1)) --> true different? In question 2, mLong127+mint1 is a long type at the end. In question 3, mShort127+mint1 is int type, we can look at the equals function,

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

We can find that only the Integer type works. We know that in jdk1.5 and above, int can be converted to an Integer object by boxing. If it is not an int type, it cannot be used. This also explains why the result of question 2 is false. mLong127+mint1 is a long type at the end, and cannot be judged as an Integer type by instanceof.
We can observe what type is passed in through the following testObject function


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";
    }

E.g

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));

The result is as follows

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

Coercion type conversion: (expression) Its function is to coerce the result of the operation of the expression into the type indicated by the type specifier.
At the same time, it is necessary to pay attention to the possibility of precision loss and even data error when converting from a large range to a small range when performing mandatory type conversion of basic types. Also note assignment operators like +=.

For example: for short a = 1; a= a+ 1; Since the type of the expression will be automatically promoted during the a+1 operation, the result is int, and when it is assigned to the short type a, the compiler will report that the type needs to be cast. mistake. 
For short a= 1; a += 1; Since += is an operator specified by the java language, the java compiler will treat it specially, so it can be compiled correctly.

Guess you like

Origin blog.csdn.net/ahou2468/article/details/122243978