@@ -416,7 +416,7 @@ public native int hashCode();
416
416
417
417
## 基本数据类型
418
418
419
- ### Java 中的几种基本数据类型是什么?对应的包装类型是什么? 各自占用多少字节呢?
419
+ ### Java 中的几种基本数据类型是什么?各自占用多少字节呢?对应的包装类型是什么 ?
420
420
421
421
Java 中有 8 种基本数据类型,分别为:
422
422
@@ -454,122 +454,46 @@ Java 中有 8 种基本数据类型,分别为:
454
454
455
455
> 《深入理解 Java 虚拟机》 :局部变量表主要存放了编译期可知的基本数据类型 ** (boolean、byte、char、short、int、float、long、double)** 、** 对象引用** (reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
456
456
457
- ### 自动装箱与拆箱
457
+ ### 包装类型的常量池技术了解么?
458
458
459
- - ** 装箱** :将基本类型用它们对应的引用类型包装起来;
460
- - ** 拆箱** :将包装类型转换为基本数据类型;
461
-
462
- 举例:
463
-
464
- ``` java
465
- Integer i = 10 ; // 装箱
466
- int n = i; // 拆箱
467
- ```
468
-
469
- 上面这两行代码对应的字节码为:
470
-
471
- ``` java
472
- L1
473
-
474
- LINENUMBER 8 L1
475
-
476
- ALOAD 0
477
-
478
- BIPUSH 10
459
+ Java 基本类型的包装类的大部分都实现了常量池技术。
479
460
480
- INVOKESTATIC java/ lang/ Integer . valueOf (I )Ljava / lang/ Integer ;
481
-
482
- PUTFIELD AutoBoxTest . i : Ljava / lang/ Integer ;
483
-
484
- L2
485
-
486
- LINENUMBER 9 L2
487
-
488
- ALOAD 0
489
-
490
- ALOAD 0
491
-
492
- GETFIELD AutoBoxTest . i : Ljava / lang/ Integer ;
493
-
494
- INVOKEVIRTUAL java/ lang/ Integer . intValue ()I
495
-
496
- PUTFIELD AutoBoxTest . n : I
497
-
498
- RETURN
499
- ```
500
-
501
- 从字节码中,我们发现装箱其实就是调用了 包装类的` valueOf() ` 方法,拆箱其实就是调用了 ` xxxValue() ` 方法。
502
-
503
- 因此,
504
-
505
- - ` Integer i = 10 ` 等价于 ` Integer i = Integer.valueOf(10) `
506
- - ` int n = i ` 等价于 ` int n = i.intValue() ` ;
507
-
508
- ### 8 种基本类型的包装类和常量池
509
-
510
- Java 基本类型的包装类的大部分都实现了常量池技术。` Byte ` ,` Short ` ,` Integer ` ,` Long ` 这 4 种包装类默认创建了数值 ** [ -128,127] ** 的相应类型的缓存数据,` Character ` 创建了数值在[ 0,127] 范围的缓存数据,` Boolean ` 直接返回 ` True ` Or ` False ` 。
461
+ ` Byte ` ,` Short ` ,` Integer ` ,` Long ` 这 4 种包装类默认创建了数值 ** [ -128,127] ** 的相应类型的缓存数据,` Character ` 创建了数值在 ** [ 0,127] ** 范围的缓存数据,` Boolean ` 直接返回 ` True ` or ` False ` 。
511
462
512
463
** Integer 缓存源码:**
513
464
514
465
``` java
515
- /**
516
-
517
- *此方法将始终缓存-128 到 127(包括端点)范围内的值,并可以缓存此范围之外的其他值。
518
-
519
- */
520
-
521
466
public static Integer valueOf(int i) {
522
-
523
467
if (i >= IntegerCache . low && i <= IntegerCache . high)
524
-
525
- return IntegerCache . cache[i + (- IntegerCache . low)];
526
-
468
+ return IntegerCache . cache[i + (- IntegerCache . low)];
527
469
return new Integer (i);
528
-
529
470
}
530
-
531
471
private static class IntegerCache {
532
-
533
472
static final int low = - 128 ;
534
-
535
473
static final int high;
536
-
537
- static final Integer cache[];
538
-
474
+ static {
475
+ // high value may be configured by property
476
+ int h = 127 ;
477
+ }
539
478
}
540
479
```
541
480
542
481
** ` Character ` 缓存源码:**
543
482
544
483
``` java
545
484
public static Character valueOf(char c) {
546
-
547
485
if (c <= 127 ) { // must cache
548
-
549
486
return CharacterCache . cache[(int )c];
550
-
551
487
}
552
-
553
488
return new Character (c);
554
-
555
489
}
556
490
557
-
558
-
559
491
private static class CharacterCache {
560
-
561
492
private CharacterCache (){}
562
-
563
-
564
-
565
493
static final Character cache[] = new Character [127 + 1 ];
566
-
567
494
static {
568
-
569
495
for (int i = 0 ; i < cache. length; i++ )
570
-
571
496
cache[i] = new Character ((char )i);
572
-
573
497
}
574
498
575
499
}
@@ -579,9 +503,7 @@ private static class CharacterCache {
579
503
580
504
``` java
581
505
public static Boolean valueOf(boolean b) {
582
-
583
506
return (b ? TRUE : FALSE );
584
-
585
507
}
586
508
```
587
509
@@ -591,31 +513,23 @@ public static Boolean valueOf(boolean b) {
591
513
592
514
``` java
593
515
Integer i1 = 33 ;
594
-
595
516
Integer i2 = 33 ;
596
-
597
517
System . out. println(i1 == i2);// 输出 true
598
518
599
519
Float i11 = 333f ;
600
-
601
520
Float i22 = 333f ;
602
-
603
521
System . out. println(i11 == i22);// 输出 false
604
522
605
523
Double i3 = 1.2 ;
606
-
607
524
Double i4 = 1.2 ;
608
-
609
525
System . out. println(i3 == i4);// 输出 false
610
526
```
611
527
612
528
下面我们来看一下问题。下面的代码的输出结果是 ` true ` 还是 ` flase ` 呢?
613
529
614
530
``` java
615
531
Integer i1 = 40 ;
616
-
617
532
Integer i2 = new Integer (40 );
618
-
619
533
System . out. println(i1== i2);
620
534
```
621
535
@@ -627,6 +541,71 @@ System.out.println(i1==i2);
627
541
628
542
![ ] ( https://img-blog.csdnimg.cn/20210422164544846.png )
629
543
544
+ ### 自动装箱与拆箱了解吗?原理是什么?
545
+
546
+ ** 什么是自动拆装箱?**
547
+
548
+ - ** 装箱** :将基本类型用它们对应的引用类型包装起来;
549
+ - ** 拆箱** :将包装类型转换为基本数据类型;
550
+
551
+ 举例:
552
+
553
+ ``` java
554
+ Integer i = 10 ; // 装箱
555
+ int n = i; // 拆箱
556
+ ```
557
+
558
+ 上面这两行代码对应的字节码为:
559
+
560
+ ``` java
561
+ L1
562
+
563
+ LINENUMBER 8 L1
564
+
565
+ ALOAD 0
566
+
567
+ BIPUSH 10
568
+
569
+ INVOKESTATIC java/ lang/ Integer . valueOf (I )Ljava / lang/ Integer ;
570
+
571
+ PUTFIELD AutoBoxTest . i : Ljava / lang/ Integer ;
572
+
573
+ L2
574
+
575
+ LINENUMBER 9 L2
576
+
577
+ ALOAD 0
578
+
579
+ ALOAD 0
580
+
581
+ GETFIELD AutoBoxTest . i : Ljava / lang/ Integer ;
582
+
583
+ INVOKEVIRTUAL java/ lang/ Integer . intValue ()I
584
+
585
+ PUTFIELD AutoBoxTest . n : I
586
+
587
+ RETURN
588
+ ```
589
+
590
+ 从字节码中,我们发现装箱其实就是调用了 包装类的` valueOf() ` 方法,拆箱其实就是调用了 ` xxxValue() ` 方法。
591
+
592
+ 因此,
593
+
594
+ - ` Integer i = 10 ` 等价于 ` Integer i = Integer.valueOf(10) `
595
+ - ` int n = i ` 等价于 ` int n = i.intValue() ` ;
596
+
597
+ 注意:** 如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作。**
598
+
599
+ ``` java
600
+ private static long sum() {
601
+ // 应该使用 long 而不是 Long
602
+ Long sum = 0L ;
603
+ for (long i = 0 ; i <= Integer . MAX_VALUE ; i++ )
604
+ sum += i;
605
+ return sum;
606
+ }
607
+ ```
608
+
630
609
## 方法(函数)
631
610
632
611
### 什么是方法的返回值?
@@ -1257,20 +1236,20 @@ public class Test {
1257
1236
Java 中类似于` InputStream ` 、` OutputStream ` 、` Scanner ` 、` PrintWriter ` 等的资源都需要我们调用` close() ` 方法来手动关闭,一般情况下我们都是通过` try-catch-finally ` 语句来实现这个需求,如下:
1258
1237
1259
1238
``` java
1260
- // 读取文本文件的内容
1261
- Scanner scanner = null ;
1262
- try {
1263
- scanner = new Scanner (new File (" D://read.txt" ));
1264
- while (scanner. hasNext()) {
1265
- System . out. println(scanner. nextLine());
1266
- }
1267
- } catch (FileNotFoundException e) {
1268
- e. printStackTrace();
1269
- } finally {
1270
- if (scanner != null ) {
1271
- scanner. close();
1272
- }
1273
- }
1239
+ // 读取文本文件的内容
1240
+ Scanner scanner = null ;
1241
+ try {
1242
+ scanner = new Scanner (new File (" D://read.txt" ));
1243
+ while (scanner. hasNext()) {
1244
+ System . out. println(scanner. nextLine());
1245
+ }
1246
+ } catch (FileNotFoundException e) {
1247
+ e. printStackTrace();
1248
+ } finally {
1249
+ if (scanner != null ) {
1250
+ scanner. close();
1251
+ }
1252
+ }
1274
1253
```
1275
1254
1276
1255
使用 Java 7 之后的 ` try-with-resources ` 语句改造上面的代码:
0 commit comments