Skip to content

Commit 4bfd01c

Browse files
committed
[feat]Java基础知识&面试题总结——基本数据类型完善
1 parent 399ee1a commit 4bfd01c

File tree

1 file changed

+88
-109
lines changed

1 file changed

+88
-109
lines changed

docs/java/basis/java基础知识总结.md

Lines changed: 88 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ public native int hashCode();
416416

417417
## 基本数据类型
418418

419-
### Java 中的几种基本数据类型是什么?对应的包装类型是什么?各自占用多少字节呢?
419+
### Java 中的几种基本数据类型是什么?各自占用多少字节呢?对应的包装类型是什么
420420

421421
Java 中有 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-
521466
public 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-
531471
private 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
545484
public 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-
559491
private 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
581505
public 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
593515
Integer i1 = 33;
594-
595516
Integer i2 = 33;
596-
597517
System.out.println(i1 == i2);// 输出 true
598518

599519
Float i11 = 333f;
600-
601520
Float i22 = 333f;
602-
603521
System.out.println(i11 == i22);// 输出 false
604522

605523
Double i3 = 1.2;
606-
607524
Double i4 = 1.2;
608-
609525
System.out.println(i3 == i4);// 输出 false
610526
```
611527

612528
下面我们来看一下问题。下面的代码的输出结果是 `true` 还是 `flase` 呢?
613529

614530
```java
615531
Integer i1 = 40;
616-
617532
Integer i2 = new Integer(40);
618-
619533
System.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 {
12571236
Java 中类似于`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

Comments
 (0)