@@ -416,7 +416,7 @@ public native int hashCode();
416416
417417## 基本数据类型
418418
419- ### Java 中的几种基本数据类型是什么?对应的包装类型是什么? 各自占用多少字节呢?
419+ ### Java 中的几种基本数据类型是什么?各自占用多少字节呢?对应的包装类型是什么 ?
420420
421421Java 中有 8 种基本数据类型,分别为:
422422
@@ -454,122 +454,46 @@ Java 中有 8 种基本数据类型,分别为:
454454
455455> 《深入理解 Java 虚拟机》 :局部变量表主要存放了编译期可知的基本数据类型 ** (boolean、byte、char、short、int、float、long、double)** 、** 对象引用** (reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
456456
457- ### 自动装箱与拆箱
457+ ### 包装类型的常量池技术了解么?
458458
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 基本类型的包装类的大部分都实现了常量池技术。
479460
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 ` 。
511462
512463** Integer 缓存源码:**
513464
514465``` java
515- /**
516-
517- *此方法将始终缓存-128 到 127(包括端点)范围内的值,并可以缓存此范围之外的其他值。
518-
519- */
520-
521466public static Integer valueOf(int i) {
522-
523467 if (i >= IntegerCache . low && i <= IntegerCache . high)
524-
525- return IntegerCache . cache[i + (- IntegerCache . low)];
526-
468+ return IntegerCache . cache[i + (- IntegerCache . low)];
527469 return new Integer (i);
528-
529470}
530-
531471private static class IntegerCache {
532-
533472 static final int low = - 128 ;
534-
535473 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+ }
539478}
540479```
541480
542481** ` Character ` 缓存源码:**
543482
544483``` java
545484public static Character valueOf(char c) {
546-
547485 if (c <= 127 ) { // must cache
548-
549486 return CharacterCache . cache[(int )c];
550-
551487 }
552-
553488 return new Character (c);
554-
555489}
556490
557-
558-
559491private static class CharacterCache {
560-
561492 private CharacterCache (){}
562-
563-
564-
565493 static final Character cache[] = new Character [127 + 1 ];
566-
567494 static {
568-
569495 for (int i = 0 ; i < cache. length; i++ )
570-
571496 cache[i] = new Character ((char )i);
572-
573497 }
574498
575499}
@@ -579,9 +503,7 @@ private static class CharacterCache {
579503
580504``` java
581505public static Boolean valueOf(boolean b) {
582-
583506 return (b ? TRUE : FALSE );
584-
585507}
586508```
587509
@@ -591,31 +513,23 @@ public static Boolean valueOf(boolean b) {
591513
592514``` java
593515Integer i1 = 33 ;
594-
595516Integer i2 = 33 ;
596-
597517System . out. println(i1 == i2);// 输出 true
598518
599519Float i11 = 333f ;
600-
601520Float i22 = 333f ;
602-
603521System . out. println(i11 == i22);// 输出 false
604522
605523Double i3 = 1.2 ;
606-
607524Double i4 = 1.2 ;
608-
609525System . out. println(i3 == i4);// 输出 false
610526```
611527
612528下面我们来看一下问题。下面的代码的输出结果是 ` true ` 还是 ` flase ` 呢?
613529
614530``` java
615531Integer i1 = 40 ;
616-
617532Integer i2 = new Integer (40 );
618-
619533System . out. println(i1== i2);
620534```
621535
@@ -627,6 +541,71 @@ System.out.println(i1==i2);
627541
628542![ ] ( https://img-blog.csdnimg.cn/20210422164544846.png )
629543
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+
630609## 方法(函数)
631610
632611### 什么是方法的返回值?
@@ -1257,20 +1236,20 @@ public class Test {
12571236Java 中类似于` InputStream ` 、` OutputStream ` 、` Scanner ` 、` PrintWriter ` 等的资源都需要我们调用` close() ` 方法来手动关闭,一般情况下我们都是通过` try-catch-finally ` 语句来实现这个需求,如下:
12581237
12591238``` 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+ }
12741253```
12751254
12761255使用 Java 7 之后的 ` try-with-resources ` 语句改造上面的代码:
0 commit comments