Java There are two types of variables in : Basic types and reference types . The basic types are 8 Kind of , Namely short,int,long,byte,char,float,double,boolean, At the same time there are 8 Reference types as their wrapper classes , for example Integer,Double etc. . This article will discuss these basic types and their packaging classes .
《2020 newest Java Basic video tutorial and learning route !》
The following part of the source code only lists some representative source code , There won't be a lot of code . I use JDK The version is JDK1.8_144
1 Integer( plastic )
Integer Is the basic type int Type of packaging . The following figure shows its inheritance system :
[](https://imgchr.com/i/ilIpdA)
[
](https://imgchr.com/i/ilIpdA)
Integer Inherited Number class , Realized Comparable that will do , Have comparable abilities , And indirectly Serializable Interface , Is serializable . In fact, the other number related packaging types are such an inheritance system , So if there is no special explanation in the following , It means inheritance system and Integer equally .
First look at it. valueOf() Method , stay Integer There are three overloaded valueOf() Method , But eventually it will call public static Integer valueOf(int i). Here is public static Integer valueOf(int i) Source code :
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Copy code
You can see , This method accepts a basic type int Parameters , And return a Integer object , It's the if Judge , It's going to be judged here i Whether in [IntegerCache.low,IntegerCache.high] In the interval , If it is, directly return the cache value , So this one low and hight What is the value of alpha ? We went to the IntegerCache Look in the class :
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;
}
private IntegerCache() {}
}
Copy code
This is a Integer An internal static class of , From code , It's not hard to see. low The value of is -128,high The default value of is 127, among high Value can be passed through java.lang.Integer.IntegerCache.high Property to set , The logic code of this class is almost all in static Block inside , That is to say, it will be executed when the class is loaded , What is the result of the implementation ? Focus on these lines of code :
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
Copy code
Put the interval in [low,hight] The values of are all constructed as Integer object , And keep it in cache In the array . Now look back valueOf() Method , Find out if the parameter i The value of the [low,hight] In the interval , So it's going to return cache Corresponding to Integer object , Words and sentences , If the parameter is in this range , You don't need to create an object to call this method , Use objects in the cache directly , Reduces the overhead of creating objects .
Then why is it so complicated ? because Java5 Provides automatic packing and automatic unpacking of grammar sugar , This method is actually for automatic packing ( As you can see from the notes , This method starts from java5 It's just beginning to happen , It can be inferred that it should be related to the automatic packing and unpacking mechanism ),Integer Is a very common class , With this caching mechanism , There's no need to create an object every time it's automatically boxed or manually called , It greatly improves the object reuse rate , It also provides operational efficiency .[-128,127] It's a more conservative area , Users can modify java.lang.Integer.IntegerCache.high To modify the high value , But it's better not to be too big , Because after all Intger Objects also take up a lot of memory , If the upper bound is set too large , And big value is not often used , So this cache is a bit of a loss .
Let's see another way intValue(), This method is very simple :
public int intValue() {
return value;
}
Copy code
value yes Integer Private field of class , The type is int, It represents the actual value , This method is actually called when unpacking automatically .
There is nothing else to say , Most are functional methods ( for example max,min,toBinaryString) And some constants ( for example MAX_VALUE,MIN_VALUE), Interested friends can check it by themselves , Algorithmic logic is not difficult .
The others will not talk about it , In understanding the Integer After the source code of , None of the others are difficult to understand .
2 Automatic packing and unpacking
Automatic packing and unpacking are Java5 Grammar sugar provided , When we need to compare between basic types and wrapper classes 、 Assignment and so on , The compiler will help us do type conversion automatically , Packing is to convert the basic type to packing type , Unpacking is the opposite process . for example , We have the following code :
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
int a = 1, b = 2, c = 3;
list.add(a);
list.add(b);
list.add(c);
}
Copy code
The compiled .class The contents of the document are as follows ( Transcoded , actually .class The file should be bytecode , But for the convenience of viewing , It's turned into java The form of the code ):
public static void main(String[] var0) {
ArrayList var1 = new ArrayList();
byte var2 = 1;
byte var3 = 2;
byte var4 = 3;
var1.add(Integer.valueOf(var2));
var1.add(Integer.valueOf(var3));
var1.add(Integer.valueOf(var4));
}
Copy code
Here comes the packing operation , The compiler helped us call Integer.valueOf() Methods will int The type has changed Integer To adapt to List Containers ( The type parameter of the container cannot be a basic type ).
Unpacking is similar , It's just the opposite of packing , This happens when the value of the wrapper type is assigned to the base type , for example :
Integer a = 1;
int b = a; // Automatic dismantling
Copy code
If there is no automatic unpacking , The above code can't be compiled , Because the type doesn't match , There was no strong turn .
More about automatic packing and unpacking , There is a lot of information on the Internet ( Very, very many ), It is suggested that interested friends can search on the Internet .
3 Choose the basic type or packing type ?
First , Let's clarify a basic principle first : If one of the basic and packaging types cannot be used in a scenario , Then we can only choose another . for example , The generic type parameter of a container cannot be a base type , Then don't hesitate , Use the packing type directly .
When both types are available , Basic types are recommended , The main reasons are as follows 3 individual :
- The wrapper type is a class , To use a value, you have to create an object , Even with caching, you can save time on creating objects , But the cost of space still exists , An object contains an object header , Instance data and object filling , But actually we just need instance data , about Integer Come on , We just need value The value of the field is just , That is to say, use the basic type int Only take up 4 Bytes of space , Using objects requires several times as much space as basic types ( You can calculate ).
- And then 1 strip , It is possible that the object is null Of , In this way, we sometimes have to judge its null value when using it , A few are OK , When business logic is complex ( Or when the programmer writes the code ), It's very easy to miss , Once omitted, a null pointer exception is likely to occur , If there is no rigorous test , It doesn't have to be tested .
Wrapper classes can sometimes be confusing when comparing , Let's take an example , Suppose you have the following code :
public static void main(String[] args) { Integer d = 220; Integer e = 220; int f = 220; System.out.println(d == e); System.out.println(e == f); } Copy code
If I haven't met such a problem , Maybe subconsciously speaking the result of execution is true and true, But actually , The output is zero false,true. Why? ? For the first comparison ,d and e All are Integer object , Direct use == Compare the actual quoted value , Not the actual value , Will be 220 When assigned to them, automatic packing actually happened , That is, called valueOf() Method , and 220 Beyond the default cache range , Then a new Interge object , these two items. a and b The quotation of is definitely not equal , So it will output false. In the second comparison ,f Is the basic type , In this case , Automatic unpacking will occur ,== The variables on both sides are actually basic types int, There is no problem in direct comparison , So the output will be true.
All in all , If you can use the basic type , It's better to use the basic type , Not its packaging , If you really can't use the basic type , For example, the generic type parameter of the container , Just use the packaging class .
4 Summary
This paper introduces Integre Packaging , A simple analysis of its source code , The reason for not analyzing other basic types of guarantee classes is that their implementations are very similar , There is no point in repeating the introduction . It also discusses the automatic packing and unpacking , This feature is convenient for programmers , Improved development efficiency , But if it is not used properly, it may cause confusing problems , There are advantages and disadvantages . For the choice between basic type and packing type , I personally prefer to use basic types first , The reasons are also explained in detail in this paper .