@@ -51,13 +51,13 @@ Java中的整型主要包含`byte`、`short`、`int`和`long`这四种,表示
51
51
### 超出范围怎么办
52
52
53
53
上面说过了,整型中,每个类型都有一定的表示范围,但是,在程序中有些计算会导致超出表示范围,即溢出。如以下代码:
54
+ ``` java
55
+ int i = Integer . MAX_VALUE ;
56
+ int j = Integer . MAX_VALUE ;
54
57
55
- int i = Integer.MAX_VALUE;
56
- int j = Integer.MAX_VALUE;
57
-
58
- int k = i + j;
59
- System.out.println("i (" + i + ") + j (" + j + ") = k (" + k + ")");
60
-
58
+ int k = i + j;
59
+ System . out. println(" i (" + i + " ) + j (" + j + " ) = k (" + k + " )" );
60
+ ```
61
61
62
62
输出结果:i (2147483647) + j (2147483647) = k (-2)
63
63
@@ -99,9 +99,9 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
99
99
反之,把包装类转换成基本数据类型的过程就是拆包装,英文对应于unboxing,中文翻译为拆箱。
100
100
101
101
在Java SE5之前,要进行装箱,可以通过以下代码:
102
-
102
+ ``` java
103
103
Integer i = new Integer (10 );
104
-
104
+ ```
105
105
106
106
## 自动拆箱与自动装箱
107
107
@@ -110,10 +110,10 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
110
110
自动装箱: 就是将基本数据类型自动转换成对应的包装类。
111
111
112
112
自动拆箱:就是将包装类自动转换成对应的基本数据类型。
113
-
113
+ ``` java
114
114
Integer i = 10 ; // 自动装箱
115
115
int b= i; // 自动拆箱
116
-
116
+ ```
117
117
118
118
` Integer i=10 ` 可以替代 ` Integer i = new Integer(10); ` ,这就是因为Java帮我们提供了自动装箱的功能,不需要开发者手动去new一个Integer对象。
119
119
@@ -122,20 +122,20 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
122
122
既然Java提供了自动拆装箱的能力,那么,我们就来看一下,到底是什么原理,Java是如何实现的自动拆装箱功能。
123
123
124
124
我们有以下自动拆装箱的代码:
125
-
125
+ ``` java
126
126
public static void main(String []args){
127
127
Integer integer= 1 ; // 装箱
128
128
int i= integer; // 拆箱
129
129
}
130
-
130
+ ```
131
131
132
132
对以上代码进行反编译后可以得到以下代码:
133
-
133
+ ``` java
134
134
public static void main(String []args){
135
135
Integer integer= Integer . valueOf(1 );
136
136
int i= integer. intValue();
137
137
}
138
-
138
+ ```
139
139
140
140
从上面反编译后的代码可以看出,int的自动装箱都是通过` Integer.valueOf() ` 方法来实现的,Integer的自动拆箱都是通过` integer.intValue ` 来实现的。如果读者感兴趣,可以试着将八种类型都反编译一遍 ,你会发现以下规律:
141
141
@@ -150,80 +150,80 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
150
150
### 场景一、将基本数据类型放入集合类
151
151
152
152
我们知道,Java中的集合类只能接收对象类型,那么以下代码为什么会不报错呢?
153
-
153
+ ``` java
154
154
List<Integer > li = new ArrayList<> ();
155
155
for (int i = 1 ; i < 50 ; i ++ ){
156
156
li. add(i);
157
157
}
158
-
158
+ ```
159
159
160
160
将上面代码进行反编译,可以得到以下代码:
161
-
161
+ ``` java
162
162
List<Integer > li = new ArrayList<> ();
163
163
for (int i = 1 ; i < 50 ; i += 2 ){
164
164
li. add(Integer . valueOf(i));
165
165
}
166
-
166
+ ```
167
167
168
168
以上,我们可以得出结论,当我们把基本数据类型放入集合类中的时候,会进行自动装箱。
169
169
170
170
### 场景二、包装类型和基本类型的大小比较
171
171
172
172
有没有人想过,当我们对Integer对象与基本类型进行大小比较的时候,实际上比较的是什么内容呢?看以下代码:
173
-
174
- Integer a=1;
175
- System.out.println(a==1?"等于":"不等于");
176
- Boolean bool=false;
177
- System.out.println(bool?"真":"假");
178
-
173
+ ``` java
174
+ Integer a= 1 ;
175
+ System . out. println(a== 1 ? " 等于" : " 不等于" );
176
+ Boolean bool= false ;
177
+ System . out. println(bool? " 真" : " 假" );
178
+ ```
179
179
180
180
对以上代码进行反编译,得到以下代码:
181
-
182
- Integer a=1;
183
- System.out.println(a.intValue()==1?"等于":"不等于");
184
- Boolean bool=false;
185
- System.out.println(bool.booleanValue?"真":"假");
186
-
181
+ ``` java
182
+ Integer a= 1 ;
183
+ System . out. println(a. intValue()== 1 ? " 等于" : " 不等于" );
184
+ Boolean bool= false ;
185
+ System . out. println(bool. booleanValue? " 真" : " 假" );
186
+ ```
187
187
188
188
可以看到,包装类与基本数据类型进行比较运算,是先将包装类进行拆箱成基本数据类型,然后进行比较的。
189
189
190
190
### 场景三、包装类型的运算
191
191
192
192
有没有人想过,当我们对Integer对象进行四则运算的时候,是如何进行的呢?看以下代码:
193
+ ``` java
194
+ Integer i = 10 ;
195
+ Integer j = 20 ;
193
196
194
- Integer i = 10;
195
- Integer j = 20;
196
-
197
- System.out.println(i+j);
198
-
197
+ System . out. println(i+ j);
198
+ ```
199
199
200
200
反编译后代码如下:
201
-
202
- Integer i = Integer.valueOf(10);
203
- Integer j = Integer.valueOf(20);
204
- System.out.println(i.intValue() + j.intValue());
205
-
201
+ ``` java
202
+ Integer i = Integer . valueOf(10 );
203
+ Integer j = Integer . valueOf(20 );
204
+ System . out. println(i. intValue() + j. intValue());
205
+ ```
206
206
207
207
我们发现,两个包装类型之间的运算,会被自动拆箱成基本类型进行。
208
208
209
209
### 场景四、三目运算符的使用
210
210
211
211
这是很多人不知道的一个场景,作者也是一次线上的血淋淋的Bug发生后才了解到的一种案例。看一个简单的三目运算符的代码:
212
-
212
+ ``` java
213
213
boolean flag = true ;
214
214
Integer i = 0 ;
215
215
int j = 1 ;
216
216
int k = flag ? i : j;
217
-
217
+ ```
218
218
219
219
很多人不知道,其实在` int k = flag ? i : j; ` 这一行,会发生自动拆箱。反编译后代码如下:
220
-
220
+ ``` java
221
221
boolean flag = true ;
222
222
Integer i = Integer . valueOf(0 );
223
223
int j = 1 ;
224
224
int k = flag ? i. intValue() : j;
225
225
System . out. println(k);
226
-
226
+ ```
227
227
228
228
这其实是三目运算符的语法规范。当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。
229
229
@@ -232,7 +232,7 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
232
232
### 场景五、函数参数与返回值
233
233
234
234
这个比较容易理解,直接上代码了:
235
-
235
+ ``` java
236
236
// 自动拆箱
237
237
public int getNum1(Integer num) {
238
238
return num;
@@ -241,12 +241,12 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
241
241
public Integer getNum2(int num) {
242
242
return num;
243
243
}
244
-
244
+ ```
245
245
246
246
## 自动拆装箱与缓存
247
247
248
248
Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先来看以下代码,猜测一下输出结果:
249
-
249
+ ``` java
250
250
public static void main(String . .. strings) {
251
251
252
252
Integer integer1 = 3 ;
@@ -264,9 +264,8 @@ Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先
264
264
System . out. println(" integer3 == integer4" );
265
265
else
266
266
System . out. println(" integer3 != integer4" );
267
-
268
267
}
269
-
268
+ ```
270
269
271
270
我们普遍认为上面的两个判断的结果都是false。虽然比较的值是相等的,但是由于比较的是对象,而对象的引用不一样,所以会认为两个if判断都是false的。在Java中,==比较的是对象应用,而equals比较的是值。所以,在这个例子中,不同的对象有不同的引用,所以在进行比较的时候都将返回false。奇怪的是,这里两个类似的if条件判断返回不同的布尔值。
272
271
@@ -321,4 +320,4 @@ Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先
321
320
322
321
[ 1 ] : http://www.hollischuang.com/archives/435
323
322
[ 2 ] : http://www.hollischuang.com/archives/1174
324
- [ 3 ] : https://www.jianshu.com/p/cc9312104876
323
+ [ 3 ] : https://www.jianshu.com/p/cc9312104876
0 commit comments