Skip to content

Commit 69db418

Browse files
authored
语法高亮
1 parent e4aa3c7 commit 69db418

File tree

1 file changed

+49
-50
lines changed

1 file changed

+49
-50
lines changed

basics/java-basic/boxing-unboxing.md

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ Java中的整型主要包含`byte`、`short`、`int`和`long`这四种,表示
5151
### 超出范围怎么办
5252

5353
上面说过了,整型中,每个类型都有一定的表示范围,但是,在程序中有些计算会导致超出表示范围,即溢出。如以下代码:
54+
```java
55+
int i = Integer.MAX_VALUE;
56+
int j = Integer.MAX_VALUE;
5457

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+
```
6161

6262
输出结果:i (2147483647) + j (2147483647) = k (-2)
6363

@@ -99,9 +99,9 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
9999
反之,把包装类转换成基本数据类型的过程就是拆包装,英文对应于unboxing,中文翻译为拆箱。
100100

101101
在Java SE5之前,要进行装箱,可以通过以下代码:
102-
102+
```java
103103
Integer i = new Integer(10);
104-
104+
```
105105

106106
## 自动拆箱与自动装箱
107107

@@ -110,10 +110,10 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
110110
自动装箱: 就是将基本数据类型自动转换成对应的包装类。
111111

112112
自动拆箱:就是将包装类自动转换成对应的基本数据类型。
113-
113+
```java
114114
Integer i =10; //自动装箱
115115
int b= i; //自动拆箱
116-
116+
```
117117

118118
`Integer i=10` 可以替代 `Integer i = new Integer(10);`,这就是因为Java帮我们提供了自动装箱的功能,不需要开发者手动去new一个Integer对象。
119119

@@ -122,20 +122,20 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
122122
既然Java提供了自动拆装箱的能力,那么,我们就来看一下,到底是什么原理,Java是如何实现的自动拆装箱功能。
123123

124124
我们有以下自动拆装箱的代码:
125-
125+
```java
126126
public static void main(String[]args){
127127
Integer integer=1; //装箱
128128
int i=integer; //拆箱
129129
}
130-
130+
```
131131

132132
对以上代码进行反编译后可以得到以下代码:
133-
133+
```java
134134
public static void main(String[]args){
135135
Integer integer=Integer.valueOf(1);
136136
int i=integer.intValue();
137137
}
138-
138+
```
139139

140140
从上面反编译后的代码可以看出,int的自动装箱都是通过`Integer.valueOf()`方法来实现的,Integer的自动拆箱都是通过`integer.intValue`来实现的。如果读者感兴趣,可以试着将八种类型都反编译一遍 ,你会发现以下规律:
141141

@@ -150,80 +150,80 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
150150
### 场景一、将基本数据类型放入集合类
151151

152152
我们知道,Java中的集合类只能接收对象类型,那么以下代码为什么会不报错呢?
153-
153+
```java
154154
List<Integer> li = new ArrayList<>();
155155
for (int i = 1; i < 50; i ++){
156156
li.add(i);
157157
}
158-
158+
```
159159

160160
将上面代码进行反编译,可以得到以下代码:
161-
161+
```java
162162
List<Integer> li = new ArrayList<>();
163163
for (int i = 1; i < 50; i += 2){
164164
li.add(Integer.valueOf(i));
165165
}
166-
166+
```
167167

168168
以上,我们可以得出结论,当我们把基本数据类型放入集合类中的时候,会进行自动装箱。
169169

170170
### 场景二、包装类型和基本类型的大小比较
171171

172172
有没有人想过,当我们对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+
```
179179

180180
对以上代码进行反编译,得到以下代码:
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+
```
187187

188188
可以看到,包装类与基本数据类型进行比较运算,是先将包装类进行拆箱成基本数据类型,然后进行比较的。
189189

190190
### 场景三、包装类型的运算
191191

192192
有没有人想过,当我们对Integer对象进行四则运算的时候,是如何进行的呢?看以下代码:
193+
```java
194+
Integer i = 10;
195+
Integer j = 20;
193196

194-
Integer i = 10;
195-
Integer j = 20;
196-
197-
System.out.println(i+j);
198-
197+
System.out.println(i+j);
198+
```
199199

200200
反编译后代码如下:
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+
```
206206

207207
我们发现,两个包装类型之间的运算,会被自动拆箱成基本类型进行。
208208

209209
### 场景四、三目运算符的使用
210210

211211
这是很多人不知道的一个场景,作者也是一次线上的血淋淋的Bug发生后才了解到的一种案例。看一个简单的三目运算符的代码:
212-
212+
```java
213213
boolean flag = true;
214214
Integer i = 0;
215215
int j = 1;
216216
int k = flag ? i : j;
217-
217+
```
218218

219219
很多人不知道,其实在`int k = flag ? i : j;`这一行,会发生自动拆箱。反编译后代码如下:
220-
220+
```java
221221
boolean flag = true;
222222
Integer i = Integer.valueOf(0);
223223
int j = 1;
224224
int k = flag ? i.intValue() : j;
225225
System.out.println(k);
226-
226+
```
227227

228228
这其实是三目运算符的语法规范。当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。
229229

@@ -232,7 +232,7 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
232232
### 场景五、函数参数与返回值
233233

234234
这个比较容易理解,直接上代码了:
235-
235+
```java
236236
//自动拆箱
237237
public int getNum1(Integer num) {
238238
return num;
@@ -241,12 +241,12 @@ Java语言是一个面向对象的语言,但是Java中的基本数据类型却
241241
public Integer getNum2(int num) {
242242
return num;
243243
}
244-
244+
```
245245

246246
## 自动拆装箱与缓存
247247

248248
Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先来看以下代码,猜测一下输出结果:
249-
249+
```java
250250
public static void main(String... strings) {
251251

252252
Integer integer1 = 3;
@@ -264,9 +264,8 @@ Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先
264264
System.out.println("integer3 == integer4");
265265
else
266266
System.out.println("integer3 != integer4");
267-
268267
}
269-
268+
```
270269

271270
我们普遍认为上面的两个判断的结果都是false。虽然比较的值是相等的,但是由于比较的是对象,而对象的引用不一样,所以会认为两个if判断都是false的。在Java中,==比较的是对象应用,而equals比较的是值。所以,在这个例子中,不同的对象有不同的引用,所以在进行比较的时候都将返回false。奇怪的是,这里两个类似的if条件判断返回不同的布尔值。
272271

@@ -321,4 +320,4 @@ Java SE的自动拆装箱还提供了一个和缓存有关的功能,我们先
321320

322321
[1]: http://www.hollischuang.com/archives/435
323322
[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

Comments
 (0)