Java--learning of packaging classes

This article introduces the packaging class in Java -- what is the packaging class, the relationship conversion between the packaging class and the basic data type -- boxing and unboxing, the valueOf and XXValue of the packaging class and the summary of the construction method, automatic boxing and Unboxing and triggering, the caching mechanism in the packaging class, some related practice questions and interview questions in the packaging class

1. Packaging

There are basic data types in java--four types and eight types of reference data types
. Compared with basic data types, it can be used to define the basic types of data, and can also be used to define the space types that store corresponding basic data.

And java is a pure object-oriented programming language, everything is an object, obviously the basic data type does not conform to this setting, because it is only used to describe the type of a data. Therefore, the wrapper class was born...

1. What is a wrapper class?

Wrapper class is a special class, which is a class type extended for existing basic data types. Wrapper class is a
reference data type generated after wrapping corresponding to various basic data types. It
is a plus version of basic data types.

Describe basic data through classes, organically combine data and methods of operating data, not only can describe a basic data type, but also describe some related attributes of this type (maximum value, minimum value...) and corresponding to this basic data type. The method (valueOf converts the string type to this basic data type)

Take Integer as an example, the packaging class corresponding to int is Integer, its internal value stores the corresponding basic data, and there are many additional static attributes such as the maximum and minimum values ​​of int Size: how many bits are occupied by int, etc...
insert image description here

2. Wrapper classes corresponding to basic data types

There are four types of basic data types and 8 types, and there are also 8 types of corresponding packaging types

basic data type Packaging
boolean (undefined) Boolean
byte (1 byte) Byte
char (2 bytes) Charcter
short (2 bytes) Short
int (4 bytes) Integer
long (8 bytes) Long
float (4 bytes) Float
double (8 bytes) Double

Except for Integer and Character, the wrapper classes of other basic types are capitalized.

3. Conversion between basic data types and wrapper class types

Each basic data type has its corresponding wrapper class, which is used to represent more specific and complete types in java, but the basic data type will be used in some calculations, comparisons or simple storage, and the two can be make the corresponding conversion

①. Boxing and unboxing

Boxing: Convert the basic data type to the corresponding packaging class
Unboxing: Convert the packaging class to the corresponding basic data type

int i = 10; // 基本数据类型 --int 定义的整形空间i 存放整形常量10

// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中

//装箱操作: 将一个基本类型的数据(int) 放到对应的包装类对象(Integer)中
Integer ii = Integer.valueOf(i);//调用Integer.valueOf方法传基本数据类型的数据(常量或者变量) 将其转换成Integer对象
Integer ij = new Integer(i);// 创建Integer对象 构造时提供对应的基本数据

// 拆箱操作:将 包装类对象(Integer)对象中的值取出放到一个基本数据类型(int) 变量中
int j = ii.intValue();// ii是Integer对象 内有成员方法intValue 即返回此对象内存储的基本数据

int and Integer are like Dagu and Ultraman
Tiga. Dagu is an ordinary person who can do relatively few things, while Tiga is Ultraman with more abilities.

Boxing means that Dagu transforms into Dijia...
Dijia is still Dagu internally, but it has many attributes and behaviors
(Dagu is an ordinary person, because of his small ability, some large-scale tasks are difficult for some special scenarios : It is necessary to transform Dagu into Dijia to fight monsters, etc.)
The packaging class is suitable for some larger and complicated tasks

Unpacking means that Tiga turns back to Dagu...
After turning back to Dagu, he is an ordinary person who no longer has those extra attributes and abilities.
In daily life, Tijia is "heavier" than Dagu in all aspects The resources occupied are also large,
and the basic data types are used to complete some simple tasks suitable for daily life

②. The valueOf and XXValue methods and construction methods of each packaging class

Because there are 8 kinds of basic data types and wrapper classes, each wrapper class has its own valueOf method and XXValue method to convert between the corresponding basic data types and wrapper classes... XX represents the value in the basic data
type some kind

Integer:
insert image description here
The valueOf of Integer mainly has two types.
One is to convert string data into corresponding wrapper class data (to facilitate the conversion of string content into specified type data) and the other
is to convert corresponding basic data types into corresponding wrapper classes (such as The valueOf of the Integer wrapper class provides conversion of int to Integer)

The XXValue method has other basic data type conversions except BooleanValue and CharValue. The meaning of the representation is to unbox the int data in the Integer packaging class object into the corresponding XX type data Character: the valueOf method provided is only one that operates
on
insert image description here
char method, because it corresponds to only one character, and a string is a collection of n characters, there is no such thing as converting n characters into one character without operating on String

XXvalue also has only one charValue method that converts Character to char, because char is character type data, which is different from other basic type data. It is a kind of character data specially corresponding to integers. It can represent English characters, Chinese characters, and English characters.
Use
insert image description here
Ascll Code (integer of -128~127) indicates that Chinese characters are represented according to different character codes (some have two bytes corresponding to a Chinese character and some have three), and the character type is intended to represent characters, so it can only be converted into the corresponding char type The XXValue method, if you need to convert it to an integer, you can force it

Boolean:
insert image description here
Boolean is the wrapper class corresponding to the boolean Boolean type. It represents only two cases of true and false, and valueOf provides conversion of boolean and String type data (the value of the string can only be " when the string is converted) true"or"false")

XXValue only has booleanValue, because Boolean data is special and not related to other types of data

Byte&Short&Integer&Long&Float&Double:
insert image description here
Taking Short as an example, there are two valueOfs provided in the six packaging classes of Byte Short Integer Long Float Double, one is to convert strings into corresponding packaging classes, and the other is to convert corresponding basic data types into packaging kind

XXValue is all 6, which is to convert this wrapper class into the basic data type corresponding to these six wrapper classes

Regarding the construction methods of the eight packaging classes, Character has only one construction method of char type,
Float, and three construction methods of float double String, and other packaging classes provide two construction methods corresponding to basic data types and String in manual boxing Pay attention when...

③. Automatic boxing and automatic unboxing

The above boxing and unboxing operations are too cumbersome. In essence, they want to achieve fast conversion between basic data types and packaging class types.
Boxing and unboxing bring a lot of code. Therefore, in order to reduce the burden on developers, java provides automatic mechanism.

int i = 10; // 基本数据

Integer ii = i; // 自动装箱
Integer ij = (Integer)i; // 自动装箱

int j = ii; // 自动拆箱
int k = (int)ii; // 自动拆箱
float f=(float) ii;

The above code realizes automatic boxing and automatic unboxing

Mainly through the = assignment operator, the basic data is directly assigned to the packaging class reference (automatic boxing)
and the packaging class object is assigned to the space defined by the basic data type (automatic unboxing)

Note: The types on both sides of auto-boxing and auto-unboxing should correspond (it cannot appear that the types do not match the internal design completely)

How is automatic boxing and automatic unboxing done?
Go to the command prompt to find the directory where the compiled and run bytecode file is located, and enter java -c bytecode file to disassemble
insert image description here
insert image description here

Through disassembly you can see:

The automatic boxing operation actually calls the valueOf method at the bottom layer. The boxing at the bottom layer helps you convert the basic data type into the corresponding packaging class. The parameters of the valueOf method called by different packaging classes are corresponding to the current packaging class. Basic data types
such as the valueOf(int) method called by int boxing

The automatic unboxing operation also calls the intValue method at the bottom layer to convert the Integer wrapper class into data of the int basic data type. Different wrapper classes call different XXValue methods
for unboxing.

Type detection about autoboxing and autounboxing:
When auto-boxing, it will check whether the type matches. The assignment between the wrapper type and the basic data type must have a type correspondence, such as Integer i=1; Float=1.0L; Long l =1L; the types on both sides must correspond, Otherwise, it will compile and report an error...
Long l=1; // At this time, the integer 1 corresponds to the packaging class Long, and if the type does not correspond, it will compile and report an error, unless it is forced

**During automatic unboxing, the type matching will be appropriately relaxed, and it will be converted to the basic data type corresponding to the packaging class during automatic unboxing. At this time, it is assigned to a variable. This variable does not need to completely match the type, and the precision is greater than or equal to the assigned value. The data is all right, the compiler will perform implicit type conversion, if the precision does not match, you need to display the forced conversion**
so you can see int k=(int)ii; when this statement is made, the (int) compiler will prompt: Casting' ii' to 'int' is redundant (it is redundant to force ii to int)
. When unboxing, ii itself is int type and no need to force it. If k is byte type, byte k=(buye)ii ; Or long k =ii ; Both are possible.
The wrapper type cannot be directly converted to the basic data type, and the basic data type cannot be directly converted to the wrapper type

Assignment operations between wrapper classes must have type matching, there will be no implicit type conversion, and it cannot be forced, such as Integer i= new Byte("1"); // type mismatch compilation error

There are implicit type conversion and coercion in assignment operations between basic data types...

④. The situation that triggers automatic boxing/unboxing

The essence of introducing automatic boxing/unboxing in java is for the convenience of writing code, but there will be some small details, which will lead to some mistakes~

The following are some situations organized by bloggers

Autoboxing:
1. When using direct assignment operation, the wrapper class type variable = basic data type;
2. When passing method parameters, the formal parameter is the wrapper class type and the actual parameter is the basic data type
3. When the method returns a value, the return type is a wrapper class type and the value returned is a basic data type

Note: Reference variables of the Object type receive basic data types and are automatically boxed, which is also applicable to method parameter passing and return values.
Because Object itself is the parent class of all classes including the wrapper class Object obj = 1L, the compiler will detect , and finally wrap 1L into a Long object and assign it to obj

Automatic unboxing:
1. When two wrapper classes or basic data perform arithmetic operations (+ - * / % | & ^ ...)
2. When two wrapper classes or wrapper class data and basic data types perform comparison operations ( > < ...) == There are special cases
3. The wrapper object will be unboxed into the basic data type and then forced to perform the forced conversion operation

Note:
1. Type correspondence is required when performing the above unboxing operations. Integer data and Long type data can be used for operations, but it should be noted that the result will be implicitly converted to a high-precision type (need to be forced according to the actual situation) but cannot be typed Does not correspond to, for example: Integer data and Boolean data (because boolean has no exact number but only indicates true and false),
but Integer and Character can be operated, because the corresponding char type data is essentially an integer...
a wrapper class and a basic data Do the same as above...

2. Wrapper classes can be unboxed into basic data types by force transfer, but basic data types cannot be boxed by force transfer wrapper classes

3. When comparing two wrapper class types, if you judge whether they are equal, you cannot use the == equal sign, because the compiler will compare them as two objects by default (the address of the object is compared)! Need to compare whether they are equal The equals method rewritten by the wrapper class needs to be called.
The operation of comparing greater than less than will be automatically unboxed, and the method CompareTo is also provided to compare the size
(when a wrapper class is compared with a basic data type equal sign, the wrapper class will be unboxed)

4. When a wrapper class compares to the basic data type for equality or size, the wrapper class will be automatically unboxed. The
.equals or compareTo method of the wrapper class can also pass the basic data type (the basic data type will be boxed, and finally passed Some conversions for comparison), the essence of compareTo is to call the compare method of Integer to compare the size of two values.
In order to avoid confusion: if there is wrapper class data when comparing the size, it is best to compare the wrapper class object with its equals method or compareTo method

insert image description here
insert image description here
insert image description here

2. The caching mechanism of the packaging class

Let's look at a piece of code before understanding the caching mechanism...

public static void main(String[] args) {
    
    
        Integer i=1;
        Integer ii=1;
        Integer j=128;
        Integer jj=128;
        Integer k=new Integer(1);
        Integer kk=new Integer(1);

        System.out.println(i==ii);
        System.out.println(j==jj);
        System.out.println(k==kk);
        //输出结果是什么?
    }

According to the above analysis, two wrapper objects are compared by == to compare the size of the object address, here are four objects, and the output should be three false, but the result is true false false
insert image description here

Why does the above situation occur?
Take the Integer wrapper class as an example:
First, auto-boxing will call the Integer.valueOf method. By observing the source code, it is found that it is not directly instantiated.
insert image description here
First, get the integer i to be boxed in the valueOf method to determine the size. If it is greater than When it is equal to low or less than or equal to high, it will return an object in the cache array of IntegerCache

private static class IntegerCache {
    
    
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
    
    
            // high value may be configured by property
            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);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
    
    
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

insert image description here

By observing the source code, it is found that there is a static internal class IntegerCache in the Integer wrapper class. When loading the external class Integer, the static internal class will be loaded. At this time, it has been determined that the value of low is -128, and high is finally obtained in the static code block modified by static The value is 127

There is also the most important cache cache array reference in IntegerCache, which will point to a reference with 256 Integers at the end,
and each Integer will point to an Integer object at the end, and the storage from the first Integer object is -128 until the second 256 objects store Integer objects with a value of 127

In a word:
when boxing, the valueOf method of Integer will be called, and the static inner class IntegerCache will be loaded, and finally there will be a cache array inside it (a total of 256 Integer objects from -128 to 127 are stored in it), when calling When the valueOf method corresponds to the integer data between [-128,127], it will directly use the pre-created Integer instance in the cache array. If it is not in this range, it will instantiate an Integr object by itself

The cache array can also be regarded as an object pool, which is a kind of resource pre-application, which is created when loading. When the object is to be used, it will check whether it already exists in the cache array, and if so, use the cache In the array, if you don’t have it, create it yourself... It can reduce the frequency of creating objects to a certain extent and improve efficiency (not necessarily, because loading will consume resources in essence. When the frequency of creating objects is low and the value value is not in the range, this The advantages of caching arrays will not be reflected)

Note: The above situation occurs only when the valueOf method is called, and the direct instantiation will not be found in the cache array

Various wrapper cache mechanisms:

Wrapper class without caching mechanism: Boolean Float Double
Boolean only has two cases of True and False, and this wrapper class is not used frequently.
Because Float and Double are all floating point numbers stored in memory, there will be precision loss problems, and it is not easy to create a cache area.

Wrapper class with caching mechanism: Byte Short Character Integer Long
Byte: -128~127 (exactly in the range of byte)
Short: -128~127
Character: 0~127 (char does not have negative numbers)
Integer: -128~127
Long: When the basic data types corresponding to -128~127
call the valueOf method to convert them into corresponding wrapper objects, the values ​​in these ranges will use the objects in the cache array generated during loading, and if they are not in the range, create objects by themselves

Why most cache areas are between -128~127
Because the cache is essentially a resource pre-application, it also creates an object, which consumes resources. If the cache area is relatively large, it will consume more resources when loading, and the cache area may not be used frequently when in use, and - The range of 128~127 is relatively small, pre-applying will not occupy too many resources, this range is also some commonly used value distribution area, and some small value calculations can not create objects frequently

3. Packaging practice questions & interview questions

1.Write the output of the following code

 public static void main(String[] args) {
    
    

        Integer i1 = 1;
        Integer i2 = 2;
        Integer i3 = 3;
        Integer i4 = 3;
        Integer i5 = 321;
        Integer i6 = 321;
        Long l1 = 3L;
        Long l2 = 2L;
        Double d1 = 100.0;
        Double d2 = 100.0;
        System.out.println(i3==i4);
        System.out.println(i5==i6);
        System.out.println(d1==d2);
        System.out.println(i3==(i1+i2));
        System.out.println(l1==(i1+i2));
        System.out.println(l1.equals(i1+i2));
        System.out.println(l1.equals(i1+l2));
        System.out.println(i3.equals(i1+i2));

        //输出结果是什么?
    }

insert image description here

The knowledge points involved are basically introduced above: the address of the same object in the buffer area is the same, and the two packaging classes of boxing and unboxing are compared with an equal sign to get the object address, and one packaging class and one basic data will be unpacked. box comparison, equals will be boxed as a wrapper class for comparison

It should be noted that the formal parameter of the equals method is accepted by the object type, and the accepted basic data type will be boxed as a wrapper class. When comparing, the two wrapper class types that must be compared must match. If they do not match, even if the value is equal false…

For example, the fifth question: even if the values ​​in Long and Integer are equal, but the types do not match...
insert image description here

2.Talk about the difference between Integer i = new Integer(xxx) and Integer i =xxx; these two methods.

Answer:
The first creation method will not trigger auto-boxing, the second creation method will trigger auto-boxing

In general, the second method is more efficient and less resource-intensive than the first method, because it may use pre-created objects from the cache array... (but not absolutely)

The above knowledge points also involve some interview knowledge points, and more questions will be collected and supplemented later... Mutual encouragement

Guess you like

Origin blog.csdn.net/lch1552493370/article/details/131872824