最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

# java查漏補缺系列_01_230813

2023-08-14 01:38 作者:Biehmltym  | 我要投稿


# java查漏補缺


我理解相對物的局限,我尊重相對物的命運。
我把你的還給你,我把我的拿回來。
塵歸塵,土歸土,你歸你,我歸我。


### 0 8大基本數(shù)據(jù)類型及包裝類? ??


Java 八大基本數(shù)據(jù)類型以及包裝類的詳解

#### 一、java中八種基本數(shù)據(jù)類型對應的包裝類型:?

?|原始類型| 包裝類 |原始類型所占的字節(jié)數(shù)? |

?|--|--|--|

?short |? ?Short? ? ?|? 2個字節(jié)? ? ? ? ? ? ? ? ? ? ? ??

?int? ?|? ? ?Integer? ? | 4個字節(jié)

?long? ? | Long? ? |? ? 8個字節(jié)

?float |? ? Float? ? |? ?4個字節(jié)

?double | Double |? 8個字節(jié)

?byte? ? |? Byte? ? ?|? ?1個字節(jié)

?char? ? ? | Character | 2個字節(jié)

?boolean| Boolean| 這個試編譯環(huán)境而定?

?

> 思考:java中提供的八種基本數(shù)據(jù)類型不夠用嗎?為什么java中還要提供對應的包裝類呢?


1. 基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換不是都可以制動轉(zhuǎn)換的,而你**強制轉(zhuǎn)換又會出問題**,比如String類型的轉(zhuǎn)換為int類型的,那么jdk為了方便用戶就提供了相應的包裝類。


2. 便于函數(shù)傳值?


3. 就是在一些地方要用到Object的時候方便將基本數(shù)據(jù)類型裝換


例子:

```java

// 聲明一個名為 "Integer" 的公共類

public class Integer {

? ? // 聲明一個私有整型成員變量 i

? ? private int i;

? ??

? ? // 構(gòu)造函數(shù),接受一個整數(shù)參數(shù) a

? ? public Integer(int a) {

? ? ? ? // 將成員變量 i 設置為傳入的參數(shù) a

? ? ? ? i = a;

? ? }

? ??

? ? // 聲明一個靜態(tài)方法 parseToInt,沒有參數(shù)

? ? public static int parseToInt() {

? ? ? ? // 返回當前類的靜態(tài)成員變量 i

? ? ? ? return i;

? ? }

? ??

? ? // 聲明一個靜態(tài)方法 valueOf,接受一個字符串參數(shù) str

? ? public static Integer valueOf(String str) {

? ? ? ? // 在這里應該有一系列的邏輯操作,將字符串 str 轉(zhuǎn)換為整數(shù)類型的 IntegerStr

? ? ? ? // 最終創(chuàng)建一個新的 Integer 對象,傳入轉(zhuǎn)換后的 IntegerStr 作為參數(shù)

? ? ? ? // 返回新創(chuàng)建的 Integer 對象

? ? ? ? return new Integer(IntegerStr);

? ? }

}

```




上面是jdk關于Integer的一個例子 比如Integer intg = Integer.valueOf(str); int i = intg.parseToInt();?

這樣用戶就很方便的完成了 String和int的轉(zhuǎn)換 這樣就方便了用戶



有時候一個函數(shù)需要傳遞一個Object的變量 而你想傳遞int類型的進去顯然不行,怎么辦呢,用到了包裝類。

```java

public void test(Object obj){

}

你想傳遞5進去就可以這樣

test(new Integer(5));

```

#### 二,包裝類的使用


以Integer為例子~

```java

public class IntegerTest{

?public static void main(String[] args){?

? //獲取int類型的最大值和最小值

? System.out.println("int最小值:" + Integer.MIN_VALUE);

? System.out.println("int最大值:" + Integer.MAX_VALUE);??

? //以int推byte

? System.out.println("byte最小值:" + Byte.MIN_VALUE);

? System.out.println("byte最大值:" + Byte.MAX_VALUE);?

? //創(chuàng)建Integer類型的對象

? Integer i1 = new Integer(10); //int--> Integer

? Integer i2 = new Integer("123"); //String --> Integer??

? System.out.println(i1); //10

? System.out.println(i2); //123??

? //以下程序編譯可以通過。但是運行的時候會報異常.數(shù)字格式化異常.

? //雖然可以將字符串轉(zhuǎn)換成Integer類型,但是該字符串也必須是"數(shù)字字符串".

? //Integer i3 = new Integer("abcd"); //NumberFormatException??

?}

}

```


效果圖:



Integer中常用的方法:

```java


public class IntegerTest1{?

?public static void main(String[] args){??

? //int-->Integer

? //基本數(shù)據(jù)類型-->引用類型

? Integer i1 = new Integer(10);??

? //Integer-->int

? //引用類型-->基本類型

? int i2 = i1.intValue();?

? System.out.println(i2 + 1); //11??

? //重要:static int parseInt(String s);

? //String-->int

? int age = Integer.parseInt("25");

? System.out.println(age+1); //26??

? //"abc"這個字符串必須是“數(shù)字字符串”才行.

? //int price = Integer.parseInt("abc"); //NumberFormatException

? //重要:static double parseDouble(String s);

? double price = Double.parseDouble("3.0");

? System.out.println(price+1.0); //4.0?

? //將int類型的十進制轉(zhuǎn)換成2進制

? String s1 = Integer.toBinaryString(10);

? System.out.println(s1); //1010?

? //將int類型的十進制轉(zhuǎn)換成16進制

? String s2 = Integer.toHexString(10);

? System.out.println(s2); //a??

? //將int類型的十進制轉(zhuǎn)換成8進制

? String s3 = Integer.toOctalString(10);

? System.out.println(s3); //12??

? //int-->Integer

? Integer i3 = Integer.valueOf(10);??

? //String--->Integer

? Integer i4 = Integer.valueOf("10");

? System.out.println(i3);

? System.out.println(i4);?

?}

}


```

包裝類的作用還是很強大的~



#### 三.裝箱和拆箱

在我們使用基本類型的包裝類時,有時肯定需要在他們之間進行轉(zhuǎn)換,例如:


Integer i = Integer.valueOf(10); //將int轉(zhuǎn)換為Integer

int i2 = i.intValue(); //將Integer轉(zhuǎn)換為int

1

2

這種把基本數(shù)據(jù)類型轉(zhuǎn)換成包裝類的過程就叫裝箱,而把包裝類轉(zhuǎn)換成基本數(shù)據(jù)類型的過程自然就稱為拆箱了;從Java SE5開始,為了減少開發(fā)人員的工作,Java提供了自動拆箱與自動裝箱功能,如果要生成一個數(shù)值為10的Integer對象,只需要這樣就可以了:

```java

Integer i = 10; //系統(tǒng)自動調(diào)用Integer.valueOf()方法來進行裝箱

int n = i; //系統(tǒng)自動調(diào)用Integer.intValue()方法進行拆箱

1

2

```

自動拆裝箱大大節(jié)省了開發(fā)人員的精力,不用再關心什么時候需要拆箱和裝箱。但是,在使用中還是有一些問題需要注意:


1)包裝類型數(shù)值的比較

示例1:


```java

Integer i1 = 100;

Integer i2 = 100;

Integer i3 = 200;

Integer i4 = 200;


System.out.println(i1==i2); //true

System.out.println(i3==i4); //false

1

2

3

4

5

6

7

```

這里我們普遍會認為兩次判斷結(jié)果都是false,因為在比較對象時判斷的是對象的引用,而不是判斷對象的值;那么這里為什么i1i2為true呢,看以下源碼我們就知道了:


public static Integer valueOf(int i) {

? ? //從下面IntegerCache實現(xiàn)中可得知IntegerCache.high默認為127

? ? ? ? if(i >= -128 && i <= IntegerCache.high)?

? ?//也就是說當初始化賦值為-128~127時,會直接返回數(shù)組中對象的引用,不會創(chuàng)建新的對象

? ? ? ? ? ? return IntegerCache.cache[i + 128];

? ? ? ? else

? ? ? ? ? ? return new Integer(i);

? ? }


private static class IntegerCache {

? ? ? ? static final int high;

? ? ? ? static final Integer cache[];

? ? ? ? static {

? ? ? ? ? ? final int low = -128;

? ? ? ? ? ? int h = 127;

? ? ? ? ? ? if (integerCacheHighPropValue != null) {

? ? ? ? ? ? ? ? int i = Long.decode(integerCacheHighPropValue).intValue();

? ? ? ? ? ? ? ? i = Math.max(i, 127);

? ? ? ? ? ? ? ? h = Math.min(i, Integer.MAX_VALUE - -low);

? ? ? ? ? ? }

? ? ? ? ? ? high = h;

? ? ? ? ? ? cache = new Integer[(high - low) + 1];

? ? ? ? ? ? int j = low;

? ? ? ? ? ? for(int k = 0; k < cache.length; k++)

? ? ? ? ? ? ? ? cache[k] = new Integer(j++);

? ? ? ? }

? ? ? ? private IntegerCache() {}

? ? }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

從源碼可以看出,在通過valueOf()方法創(chuàng)建Integer對象時,如果賦值在-128~127之間,就返回指向IntegerCache.cache中已經(jīng)存在的對象的引用;否則創(chuàng)建一個新的Integer對象。


上面i1和i2的數(shù)值為100,因此會直接從cache中取已經(jīng)存在的對象,所以i1和i2指向的是同一個對象,而i3和i4則指向新創(chuàng)建的不同對象。


示例2:


?Double i1 = 100.0;

?Double i2 = 100.0;

?Double i3 = 200.0;

?Double i4 = 200.0;

?System.out.println(i1==i2); //false

?System.out.println(i3==i4); //false

1

2

3

4

5

6

經(jīng)過了上面Integer數(shù)值的比較,這里大家會條件反射的認為i1==i2應該輸出true,但Double類的valueOf方法與Integer類的valueOf方法實現(xiàn)并不相同,因為在限定范圍內(nèi)整數(shù)的個數(shù)是有限的,而浮點數(shù)卻不是。


注意,Integer、Short、Byte、Character、Long這幾個類的valueOf()方法的實現(xiàn)是類似的,都存在-128~127的緩存池。Double、Float的valueOf方法的實現(xiàn)是類似的,不存在緩存池。


示例3:


Boolean i1 = false;

Boolean i2 = false;

Boolean i3 = true;

Boolean i4 = true;


System.out.println(i1==i2); //true

System.out.println(i3==i4); //true

1

2

3

4

5

6

7

因為Boolean底層valueOf()方法返回值始終是兩個常量TRUE和FALSE的引用,所以這里輸出都是true:


public static Boolean valueOf(boolean b) {

? ? ? ? return (b ? TRUE : FALSE);

? ? }


public static final Boolean TRUE = new Boolean(true);

public static final Boolean FALSE = new Boolean(false);

1

2

3

4

5

6

2)包裝類型運算及比較時的拆裝箱


Integer a = 1;

Integer b = 2;

Integer c = 3;

Long d = 3L;

Long e = 2L;


System.out.println(c==(a+b));? ? //true

System.out.println(c.equals(a+b));? ? //true

System.out.println(d==(a+b));? ? //true

System.out.println(d.equals(a+b));? ? //false

System.out.println(d.equals(a+e));? ? //true

1

2

3

4

5

6

7

8

9

10

11

這里需要注意的是,當 "=="運算符的兩個操作數(shù)都是包裝類型的引用,則比較指向的是否為同一個對象;而如果其中有一個操作數(shù)是表達式(即包含算術(shù)運算)則比較的是數(shù)值(即會觸發(fā)自動拆箱的過程)。另外,對于包裝類型,equals()方法不會進行類型轉(zhuǎn)換。


所以上面c==(a+b)中,a+b包含了算術(shù)運算,因此會觸發(fā)自動拆箱過程,它們比較的是數(shù)值是否相等;


而c.equals(a+b)會先觸發(fā)自動拆箱過程,再觸發(fā)自動裝箱過程,也就是說a+b,會先各自調(diào)用intValue方法,得到了加法運算后的數(shù)值之后,便調(diào)用Integer.valueOf方法,再進行equals比較。


同理對于后面的也是這樣,不過要注意d.equals(a+b)和d.equals(a+e)輸出的結(jié)果(如果數(shù)值是int類型的,裝箱過程調(diào)用的是Integer.valueOf;如果是long類型的,裝箱調(diào)用的Long.valueOf方法)。


#### 四、對象池



在Java中,對象池優(yōu)化主要適用于一些整數(shù)和字符的包裝類,而不僅僅限于 int 類型。具體來說,整數(shù)和字符包裝類在某些范圍內(nèi)會使用對象池來優(yōu)化內(nèi)存使用和性能。


這些包裝類包括:


Integer: 范圍 -128 到 127 之間的整數(shù)會使用對象池。

Byte: 范圍 -128 到 127 之間的字節(jié)會使用對象池。

Short: 范圍 -128 到 127 之間的短整數(shù)會使用對象池。

Character: 所有字符(Unicode值)都會使用對象池。

其他的包裝類,比如 Long、Float、Double,并沒有類似的對象池機制,每個值都對應一個新的對象。


#### 五 ==和equals



```java



3. 請選擇正確的一項()

? public static void main(String[] args) {

? Integer i1 = 100;

? Integer i2 = 100;

? System.out.println(i1==i2);??

? }

?

□ A.編譯錯誤

□ B.編譯錯誤

?C.控制臺輸出true?

□ D.控制臺輸出false

作答結(jié)果:?

正解:C

解析:

你創(chuàng)建了兩個 Integer 類型的對象 i1 和 i2,并將它們都初始化為整數(shù)值 100。然后,你通過 == 運算符比較了這兩個對象的引用。讓我為你解釋一下結(jié)果為什么是怎樣的。


在 Java 中,對于 Integer 類型的對象,Java 會自動進行對象池優(yōu)化,特別是在范圍從 -128 到 127 內(nèi)的整數(shù)。這意味著在這個范圍內(nèi)的整數(shù)值,每次都會返回同一個對象的引用,以減少內(nèi)存使用。


因此,對于你的代碼中的情況,i1 和 i2 都被賦值為 100,而且它們的值在對象池的范圍內(nèi),所以它們會引用相同的 Integer 對象。這就是為什么 i1 == i2 的比較會返回 true。


然而,如果你將 i1 和 i2 的值設定為超出對象池范圍的整數(shù),比如 1000,那么 i1 == i2 的比較將返回 false,因為它們引用的將是不同的 Integer 對象。


java

------------------------------------------------------------------------------------------------------------------------

4.請選擇正確的一項()

? public static void main(String[] args) {

? Double i1 = 100.0;

? Double i2 = 100.0;

? System.out.println(i1==i2);??

? }

?

□ A.編譯錯誤? ?

□ B.運行錯誤

□ C.

控制臺輸出true

?D.

控制臺輸出false??

作答結(jié)果:?

正解:D

解析:? 每個Double都是一個新的對象


創(chuàng)建了兩個 Double 類型的對象 i1 和 i2,并將它們都初始化為 100.0。

然后,通過 == 運算符比較了這兩個對象。讓我來解釋一下結(jié)果false:


在 Java 中,基本數(shù)據(jù)類型的比較可以使用 == 運算符,但對于對象類型(包括包裝類,如 Double)的比較,== 運算符比較的是對象的引用(內(nèi)存地址),而不是對象的內(nèi)容(純數(shù)值)。


在代碼中,盡管 i1 和 i2 的值都是 100.0,但它們是不同的對象,它們有不同的內(nèi)存地址空間中。因此,i1 == i2 的比較將會返回 false,因為它們引用的是不同的對象。


如果你想比較兩個 Double 對象的值是否相等,應該使用 .equals() 方法。這個方法會只比較對象的內(nèi)容,而不是嚴格地比較引用的地址。

------------------------------------------------------------------------------------------------------------------------

5.請選擇正確的一項()

? public static void main(String[] args) {

? Integer i1 = 130;

? Integer i2 =? 130;

? System.out.println(i1==i2);??

? }

??

□ A.編譯錯誤? ?

□ B.編譯錯誤? ?

□ C.控制臺輸出true

?D.控制臺輸出false?

作答結(jié)果:?

正解:D

解析:

對于 Integer 類型的對象,Java 在一定范圍內(nèi)(-128 到 127)使用了對象池(也稱為緩存),以優(yōu)化內(nèi)存使用和性能。在這個范圍內(nèi),每個整數(shù)值對應一個唯一的對象,這意味著相同的值的 Integer 對象會引用相同的對象。


在你的代碼中,130 并不在對象池范圍內(nèi),因此 i1 和 i2 引用的是不同的 Integer 對象。因此,i1 == i2 的比較會返回 false,因為它們引用的是不同的對象。==比較的是不同對象的地址值。

------------------------------------------------------------------------------------------------------------------------

6.請選擇正確的一項()

? public static void main(String[] args) {

? Integer i1 = 130;

? Double? i2 =? 130.0;

? System.out.println(i1==i2);??

? }

?

? A.編譯錯誤? ?

□ B.運行錯誤

□ C.控制臺輸出true? ?

□D.控制臺輸出false?

作答結(jié)果:?

正解:A


?//java: 不可比較的類型: java.lang.Integer和java.lang.Double


改為equals 則編譯通過,輸出false 因為 是兩個不同的引用對象。

解析:

------------------------------------------------------------------------------------------------------------------------

7.請選擇正確的一項()

? public static void main(String[] args) {

? Integer i1 = 130;

? Double? i2 =? 130.0;

? System.out.println(i1.equals(i2));??

? }

?

□ A.編譯錯誤

□ B.運行錯誤

□ C.控制臺輸出true?

?D.控制臺輸出false?

作答結(jié)果:?

正解:D

解析:

------------------------------------------------------------------------------------------------------------------------

8.請選擇正確的一項()

? public static void main(String[] args) {

? Integer? i1 =? ?new Integer(10);

? Integer? i2 =? ?new Integer(10);

? System.out.println(i1 == i2);??

? }

?

□ A.編譯錯誤?

□ B.運行錯誤

□ C.控制臺輸出true? ?

?D.控制臺輸出false?

作答結(jié)果:?

正解:D

解析:? 使用 new Integer(10) 創(chuàng)建的 Integer 對象會在堆上創(chuàng)建不同的對象,而使用 Integer.valueOf(10) 可以利用對象池,使相同值的對象引用相同的對象,提高性能和內(nèi)存效率。

------------------------------------------------------------------------------------------------------------------------

9.請選擇正確的一項()

? public static void main(String[] args) {

? Integer i1 = 10;

? Integer i2 = Integer.valueOf(10);

? Integer i3 = new Integer(10);

? ? ? ? ? System.out.println(i1 == i2);??

? System.out.println(i2 == i3);??

? }

??

□ A.控制臺打印true和true

□ B.控制臺打印false和false

?C.控制臺打印true和false

□ D.控制臺打印false和true

作答結(jié)果:?

正解:C

解析:


代碼中,進行了不同方式創(chuàng)建 Integer 對象的比較,使用了自動裝箱、靜態(tài)工廠方法和顯式地使用構(gòu)造函數(shù)。讓我為你逐一解釋結(jié)果為什么是怎樣的。


Integer i1 = 10;:這是自動裝箱的方式,Java 會將基本數(shù)據(jù)類型的值自動轉(zhuǎn)換為對應的包裝類對象。在范圍內(nèi)的整數(shù)值(-128 到 127)會使用對象池優(yōu)化,相同值的對象引用相同的對象,所以 i1 和 i2 都引用相同的對象,i1 == i2 的比較會返回 true。

Integer i2 = Integer.valueOf(10);:使用 Integer.valueOf 靜態(tài)工廠方法創(chuàng)建 Integer 對象。與上面相同的值范圍內(nèi),也會使用對象池優(yōu)化,所以 i2 和 i1 引用相同的對象,i2 == i1 的比較同樣會返回 true。

Integer i3 = new Integer(10);:顯式地使用構(gòu)造函數(shù)創(chuàng)建 Integer 對象。無論值是否在范圍內(nèi),使用構(gòu)造函數(shù)都會在堆上創(chuàng)建新的對象,所以 i3 引用一個不同的對象。因此,i2 == i3 的比較會返回 false,因為它們引用的是不同的對象。

------------------------------------------------------------------------------------------------------------------------

10.選擇不是 Java語言中的基本數(shù)據(jù)類型的選項()

? ?   

? ?

□ A.byte 

□ B.long 

?C.String 

□ D.char 

作答結(jié)果:?

正解:C

解析:

------------------------------------------------------------------------------------------------------------------------

11.package run;

? ?

? ?public class Run{

? ?/*題目:8個基本類型及包裝類基礎練習-1

? ?*/

? ?public static void main(String[] args) {

? ?int i = 20;

? ?//將int類型轉(zhuǎn)換為包裝類型

? ?Integer wrapperi = __new___ Integer(i);

? ?//將包裝類型轉(zhuǎn)換為基本類型

? ?int j = __wrapperi___.intValue();

? ?//將Integer 轉(zhuǎn)換為String類型

? ?String str = wrapperi.toString();

? ?//將String 轉(zhuǎn)換為Integer類型

? ?Integer k = Integer.__valueOf___(str);

? ?//將Integer 轉(zhuǎn)換為Double類型

? ?Double d = wrapperi.doubleValue();

? ?}

? ?}

? ?請根據(jù)注釋補全代碼

作答結(jié)果:?

正解:

①new

②wrapperi

③valueOf

解析:

12.package run;

? ?

? ?public class Run {

? ?

? ?/*題目:8個基本類型及包裝類基礎練習-2

? ?需求:

? ?1.定義靜態(tài)方法getInteger,傳入一參int類型,方法體返回對應Integer包裝類型對象

? ?2.定義靜態(tài)方法getInt,傳入一參Integer包裝類型對象類型,方法體返回對應int值

? ?3.定義靜態(tài)方法getCharacter,傳入一參char類型,方法體返回對應Character包裝類型對象

? ?4.定義靜態(tài)方法getChar,傳入一參Character包裝類型對象類型,方法體返回對應char值

? ?*/? ? ?

? ? ? ?public static Integer getInteger(int i){

? ? ? ?return new Integer(i);

? ? ? ?}

? ? ? ?public static int getInt(Integer __wrapper___){

? ? ? ?return wrapper.intValue();

? ? ? ?}

? ? ? ?public static Character getCharacter(char c){

? ? ? ?return new Character(__c___);

? ? ? ?}

? ? ? ?public static char getChar(__Character___ wrapper){

? ? ? ?__return___ wrapper.charValue();

? ? ? ?}

? ?}

? ?請根據(jù)注釋補全代碼

作答結(jié)果:?

正解:

①wrapper

②c

③Character

④return

解析:

13.package run;

? ?

? ?public class Run {

? ?/*題目:8個基本類型及包裝類基礎練習-3

? ?需求:

? ?1.定義靜態(tài)方法getLongObject,傳入一參long類型,方法體返回對應Long包裝類型對象

? ?2.定義靜態(tài)方法getLong,傳入一參Long包裝類型對象類型,方法體返回對應int值

? ?3.定義靜態(tài)方法getBooleanObject,傳入一參boolean類型,方法體返回對應Boolean包裝類型對象

? ?4.定義靜態(tài)方法getBoolean,傳入一參Boolean包裝類型對象類型,方法體返回對應boolean值

? ?*/? ? ?

? ? ? ?public static Long getLongObject(long l){

? ? ? ?return new __Long___(l);

? ? ? ?}

? ? ? ?public static long getLong(Long wrapper){

? ? ? ?return wrapper.longValue();

? ? ? ?}

? ? ? ?public static Boolean getBooleanObject(booleanb){

? ? ? ?return _____ Boolean(b);

? ? ? ?}

? ? ? ?public static boolean getBoolean(Boolean wrapper){

? ? ? ?return wrapper.__booleanValue___();

? ? ? ?}

? ?}

? ?請根據(jù)注釋補全代碼

作答結(jié)果:?

正解:

①Long

②new

③booleanValue

解析:



```


***


###? 1.? ?javac HelloWorld.java??

###? java 運行.class文件

javac命令可以編譯.java文件? ?編譯.java 文件為 .c lass 文件---》javaC命令?

###? 2. 關于配置環(huán)境變量path作用的說法中,正確的是( )??

?- 在任意路徑使用java和javac等命令??

?- 配置完path后,要重啟cmd命令窗口才可生效??

?- 配置完環(huán)境變量path的情況下,在C:\Users\Administrator\Desktop路徑使用java命令,優(yōu)先查找path路徑??

###? 3. classpath路徑應設置為jdk安裝路徑下的bin路徑??

在Java中,classpath 是一個用于指定類文件(.class 文件)或資源文件(如配置文件、圖像等)的路徑。它不僅僅是設置為JDK安裝路徑下的bin路徑,而是可以指定為包含類文件或資源文件的任何目錄路徑。


?classpath 是一個重要的概念,它用于告訴Java虛擬機(JVM)在哪里查找類文件或資源文件以進行加載。有幾種不同的方式可以設置 classpath。


命令行設置: 在運行Java程序時,可以使用 -cp 或 -classpath 參數(shù)來設置類路徑。例如:

bash

Copy code

java -cp /path/to/classes MyApp

環(huán)境變量: 你可以設置一個名為 CLASSPATH 的環(huán)境變量來指定類路徑。多個路徑可以使用分號(Windows)或冒號(Linux/macOS)分隔。

在代碼中設置: 在代碼中,你也可以使用 System.setProperty("java.class.path", "/path/to/classes"); 來動態(tài)設置類路徑。

通常情況下,將類文件和資源文件放在不同的目錄中,并將這些目錄都添加到 classpath 中,以便Java程序可以正確地加載它們。


總之,classpath 是用于指定類文件或資源文件位置的重要機制,你可以根據(jù)實際需要設置為適當?shù)哪夸浡窂健?/p>

### 4 .下列關于說法正確的是( )?

?常用DOS命令,cd 是進入指定目錄??

?常用DOS命令, cd ..代表返回上路徑??

?jdk,jre,jvm三者關系是jdk中包含jre,jre中包含jvm??

?

3.關于Eclipse:


- eclipse 支持插件式開發(fā)??

- 3.3版本之前,eclipse不能開發(fā)web項目??

- eclipse支持多語言開發(fā)java、C++、c等

-? SVN插件用于管理代碼的版本(version)??



### 總結(jié)eclipse:

Eclipse 是一個非常流行的**集成開發(fā)環(huán)境(IDE)**,可以用于開發(fā) Java 程序以及多種其他類型的應用程序。以下是 Eclipse 的一些主要特點和用途:


特點:


#### 多語言支持:?

Eclipse 不僅僅用于 Java 開發(fā),還支持多種編程語言,如C/C++、Python、PHP等。

#### 插件架構(gòu):

?Eclipse 采用插件式架構(gòu),允許開發(fā)者安裝和使用各種插件來擴展和定制 IDE 功能。

#### 強大的調(diào)試工具:?

Eclipse 提供了豐富的調(diào)試功能,允許逐步執(zhí)行代碼并檢查變量的值和執(zhí)行過程。

#### 代碼自動完成:

?Eclipse 提供代碼自動完成功能,可以大大提高編碼的效率。

#### 版本控制集成:?

Eclipse 集成了版本控制系統(tǒng),如Git、SVN等,方便團隊協(xié)作和源代碼管理。


### "metadata" 文件


在許多軟件開發(fā)環(huán)境中,特別是與代碼編輯、項目管理和集成開發(fā)環(huán)境(IDE)有關的情況下,"metadata" 文件夾通常用于保存與工作區(qū)(Workspace)或項目相關的設置、配置和元數(shù)據(jù)信息。



### 使用eclipse物理刪除時不一定同時會刪除硬盤上的文件,取決于你的操作和設置。

?



### 在 Eclipse 或其他類似的集成開發(fā)環(huán)境中,刪除文件時的行為取決于你的操作和設置。




通常情況下,Eclipse 刪除文件時會有兩個選項:邏輯刪除和物理刪除。


邏輯刪除: 在邏輯刪除情況下,Eclipse 會將文件標記為已刪除,但不會立即從硬盤上移除。你可能不再在工作區(qū)中看到這個文件,但它實際上仍然存在于你的文件系統(tǒng)中。

物理刪除: 物理刪除是指文件會被徹底從硬盤上刪除,無法恢復。在 Eclipse 中進行物理刪除時,文件會被徹底移除,而不是僅僅在工作區(qū)中標記為已刪除。

默認情況下,Eclipse 在刪除文件時可能會執(zhí)行邏輯刪除,將文件移到回收站或 Trash 文件夾中,而不會立即從硬盤上刪除。這是為了防止意外刪除造成不可恢復的損失。如果你想要徹底刪除文件,通??梢允褂?Shift + Delete 鍵盤組合或選擇 "徹底刪除" 選項來執(zhí)行物理刪除。


然而,確切的行為可能會因 Eclipse 版本、操作系統(tǒng)以及配置而有所不同。在執(zhí)行刪除操作時,最好在確認對話框中查看選項以確保你了解將要執(zhí)行的操作。如果你關心文件的安全,請務必備份重要文件,以防萬一。



### - 導入maven項目 跟一般項目方式相似,**但不同**。

### - 導入既存項目時可以**拷貝整個**工作空間??

### - 導入既存項目時可以拷貝項目,**進行import導入操作 **?


### Java語言提供了八種基本類型。

六種數(shù)字類型(四個整數(shù)型byte short int long? long a = 100000L,兩個浮點型float double? 例子:float f1 = 234.5f。

),

一種字符類型, char?

還有一種布爾型。 boolean

整數(shù)的默認類型是 int。

小數(shù)默認是 double 類型浮點型,

在定義 float 類型時必須在數(shù)字后面跟上 F 或者 f。



###? 數(shù)據(jù)類型轉(zhuǎn)換

整型、實型(常量)、字符型數(shù)據(jù)可以混合運算。運算中,不同類型的數(shù)據(jù)先轉(zhuǎn)化為同一類型,然后進行運算。


#### 數(shù)據(jù)類型轉(zhuǎn)換必須滿足如下規(guī)則:

1. 不能 對boolean類型進行類型轉(zhuǎn)換。

2. 不能 把對象類型轉(zhuǎn)換成不相關類的對象。

3. 在把容量大 的類型轉(zhuǎn)換為容量小的類型時必須使用強制類型轉(zhuǎn)換。

而且 ,轉(zhuǎn)換過程中可能導致溢出或損失精度,例如:

```java

int i =128;? ?

byte b = (byte)i;

```

4. 浮點數(shù)到整數(shù)的轉(zhuǎn)換是通過**舍棄小數(shù)**得到,而不是四舍五入,例如:

(int)23.7 == 23;? ? ? ??

(int)-45.89f == -45


因為 byte 類型是 8 位,最大值為127,所以當 int 強制轉(zhuǎn)換為 byte 類型時,值 128 時候就會導致溢出。

5. 浮點數(shù)到整數(shù)的轉(zhuǎn)換是通過舍棄小數(shù)得到,而不是四舍五入,例如:

(int)23.7 == 23;? ? ? ??

(int)-45.89f == -45



### 數(shù)據(jù)的從低級到高級。 自動類型提升?

低? ------------------------------------>? 高


### byte,short,char—>int—>long—>float—>double?

強制類型轉(zhuǎn)換后?


byte, short,char -> int -> long -> float -> double

```java

//double到int 高到低?

System.out.println((int)23.7); //23丟失精度

char c = 'a';// char< int 好事 自動提升容量 字符自動提升為int數(shù)字?

int n = c+1;

System.out.println(n); //98


//但是 當int 數(shù)字 向下轉(zhuǎn)換為 char 要強行剝奪 int的高級 才能轉(zhuǎn)換為 char?


System.out.println((char)n); //b



```


### 5. 控制臺輸出結(jié)果()

? ?int a? = 1;

? ?double b = 1.2;

? ?// a = 0;

? ?System.out.println(a+b);

? ?

? ?

? ?輸出結(jié)果應為:2.2。因為在這段代碼中,整數(shù)類型的a和浮點數(shù)類型的b相加,Java會自動進行類型提升,將a轉(zhuǎn)換為浮點數(shù),然后再進行加法運算。

? ?

? ?

### 6.int a = 4;? a++ ++a +=?

#### i++ 與 ++i 的主要區(qū)別有兩個:

2.1、i++ 直接返回原來的值,++i 返回加1后的值。

2.2、i++ 不能作為左值,而++i 可以。

a:量子改變,一變百變。



####? ? 執(zhí)行以下五種情況

(1) a += a++; //a=?

(2) a += ++a; //a=?

(3) ++a += a; //a=?

(4) ++a += a++; //a=?

(5) ++a += ++a; //a=?

#### 運算優(yōu)先級

##### **前綴**++a/–a**優(yōu)先級大于**所有數(shù)值運算符

##### **后綴**a++/a–**優(yōu)先級小于**所有數(shù)值運算符

###### 答案:

(1) a + a = a8? +1 = a9 //9

(2) a++ = a5 + a5 =? a10 //10??

(3) a+1=a5? +a5 =? a10//10

(4) (a+1 = a5? + a5=a10)+1=a11 //11

(5) (a+1 = a5? +1 = a6 + a6 = a12 //12



###### 詳細解釋:


(1) a += a++;


后綴++的優(yōu)先級小于+=的優(yōu)先級,因此先執(zhí)行a+=a的操作,得8,然后再執(zhí)行a++的操作,結(jié)果為9


(2) a += ++a;


前綴++的優(yōu)先級大于+=的優(yōu)先級,因此先執(zhí)行++a的操作,得5,然后再執(zhí)行a+=a的操作,結(jié)果為10


(3) ++a += a;


前綴++的優(yōu)先級大于+=的優(yōu)先級,因此先執(zhí)行++a的操作,得5,然后再執(zhí)行a+=a的操作,結(jié)果為10


(4) ++a += a++;


優(yōu)先級:前綴++ > += > 后綴++,先執(zhí)行++a得5,然后執(zhí)行a+=a得10,最后執(zhí)行a++得11


(5) ++a += ++a;


對于同時前綴的,順序是從左往右,因此先執(zhí)行左邊的++a得5,然后執(zhí)行右邊的++a得6,最后執(zhí)行a+=a得12




### 7. a--和--a的區(qū)別.? ?

a-- 是**先引用**后減少,先在a所在的表達式中使用**a的當前值**,后讓a減1;?

?--a 是先減少后引用,**讓a先減1**,然后在a所在的表達式中**使用a的新值**

?

?

###? 8. int a = 6;? double b = 6.0; ==時 自動向上提升

System.out.println(a == b);//true


?System.out.println(a == b);:這一行使用 == 運算符來比較變量 a 和 b 是否相等。由于 a 是整數(shù),而 b 是浮點數(shù),它們的數(shù)據(jù)類型不同,所以在比較時會發(fā)生類型轉(zhuǎn)換。在這種情況下,整數(shù) a 會被自動轉(zhuǎn)換為浮點數(shù),然后進行比較。因此,比較的實際是 6.0 == 6.0,這個條件是成立的。

?

### 9. & 和 &&?

#### & 邏輯與運算符:

即使左邊的表達式為 false,右邊的表達式也會被計算,這可能導致不必要的計算。

#### && 邏輯與運算符:

如果左邊的表達式為 false,則右邊的表達式不會被計算,因為整個邏輯表達式的結(jié)果已經(jīng)可以確定為 false,從而避免了不必要的計算。

&& 是一個短路運算符,它在布爾邏輯中執(zhí)行邏輯與操作,并且只在必要時計算右邊的表達式。





### 10. int b = 5;

b = ((b-- > 3) && (--b < 3)) ? b++ : b--;

System.out.println(b);// 輸出 3?



1? int b = 5;:將變量 b 初始化為 5。

2? b = ((b-- > 3) && (--b < 3)) ? b++ : b--;:


首先,進行條件表達式的計算。


b-- > 3:這是一個條件判斷,檢查 b 是否大于 3。因為 b 是 5,所以這個條件為 true。然后 b 的值會先被使用,變?yōu)?4。

--b < 3:這是另一個條件判斷,檢查 b 自減后是否小于 3。由于 b 在上一個條件判斷中變?yōu)?4,自減后變?yōu)?3,所以這個條件為 false。

((true) && (false)):由于兩個條件判斷的結(jié)果是 true 和 false,所以整個條件表達式的結(jié)果為 false。

因此,執(zhí)行 b--,b 的值減少為 3。

System.out.println(b);:打印變量 b 的值,即 3。



### 11 java 有匿名類 匿名方法

匿名類:


在 Java 中,你可以創(chuàng)建一個沒有顯式命名的類,稱為匿名類。匿名類通常用于實現(xiàn)接口或擴展類,而無需為其創(chuàng)建專門的類文件

```java

public class AnonymousClassExample {

? ? public static void main(String[] args) {

? ? ? ? Thread thread = new Thread(new Runnable() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void run() {

? ? ? ? ? ? ? ? System.out.println("Thread is running.");

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? thread.start();

? ? }

}


```



### 匿名方法(匿名函數(shù)):

方法包含于類或?qū)ο笾校?/p>

方法在程序中被創(chuàng)建,在其他地方被引用。

設計方法的原則:方法的本意是功能塊,就是實現(xiàn)某個功能的語句塊的集合。我們設計方法的時候,最好保持方法的原子性,就是一個方法只完成1個功能,這樣利于我們后期的擴展。



Java 8 引入了 Lambda 表達式,它是一種匿名方法(匿名函數(shù))的形式。Lambda 表達式允許你以更緊湊的方式定義匿名函數(shù),并可以在函數(shù)式接口(只有一個抽象方法的接口)中使用。


示例:使用 Lambda 表達式實現(xiàn)一個簡單的接口。

```java

interface MathOperation {

? ? int operate(int a, int b);

}


public class AnonymousMethodExample {

? ? public static void main(String[] args) {

? ? ? ? MathOperation addition = (a, b) -> a + b;

? ? ? ? System.out.println("Result: " + addition.operate(5, 3));

? ? }

}


```


在這個示例中,我們通過 Lambda 表達式實現(xiàn)了一個函數(shù)式接口 MathOperation,定義了一個匿名方法來執(zhí)行加法操作。


匿名類和匿名方法都使代碼更加簡潔,并且在某些情況下可以提高代碼的可讀性和可維護性。



### 12 方法必須有方法名嗎?



###### 大多數(shù)情況下,函數(shù)或方法需要一個方法名:


在大多數(shù)編程語言中,函數(shù)或方法需要一個獨特的方法名來標識它們。方法名用于在代碼中引用和調(diào)用該函數(shù)或方法,以便執(zhí)行其功能。方法名的存在使得代碼的可讀性和可維護性更高,因為其他開發(fā)人員可以通過方法名理解函數(shù)的用途和功能。


###### 匿名函數(shù)(Lambda 表達式):


然而,一些現(xiàn)代編程語言(例如 Java 8+、Python、JavaScript 等)引入了匿名函數(shù)的概念,也稱為 Lambda 表達式。匿名函數(shù)是一種沒有顯式方法名的函數(shù),通常用于在函數(shù)式編程范式中傳遞行為。


在匿名函數(shù)中,沒有單獨的方法名,而是通過函數(shù)參數(shù)傳遞行為。這種方式使代碼更具有靈活性,可以將函數(shù)作為參數(shù)傳遞給其他函數(shù)或方法。


示例:Java 中的 Lambda 表達式

```java

interface MathOperation {

? ? int operate(int a, int b);

}


public class LambdaExample {

? ? public static void main(String[] args) {

? ? ? ? MathOperation addition = (a, b) -> a + b;

? ? ? ? int result = addition.operate(5, 3);

? ? ? ? System.out.println("Result: " + result);

? ? }

}


```


### 13? 方法可以沒有方法體??


在一些特殊情況下的方法,它們可能沒有方法體或只包含方法的聲明。這通常用于**抽象類、接口、抽象方法等**概念中。讓我為你解釋一下:


#### 抽象方法:


在面向?qū)ο缶幊讨校橄蠓椒ㄊ且环N沒有具體實現(xiàn)的方法,它只有方法的聲明,而沒有方法體。抽象方法必須位于抽象類或接口中,它是一種為了讓子類或?qū)崿F(xiàn)類來實現(xiàn)的方法。


在 Java 中,抽象方法用 abstract 關鍵字聲明,示例如下:


```java

abstract class Shape {

? ? abstract void draw(); // 抽象方法聲明,沒有方法體

}


class Circle extends Shape {

? ? @Override

? ? void draw() {

? ? ? ? System.out.println("Drawing a circle");

? ? }

}




public class AbstractMethodExample {

? ? public static void main(String[] args) {

? ? ? ? Circle circle = new Circle();

? ? ? ? circle.draw();

? ? }

}


```



在這個示例中,Shape 類中的 draw 方法是一個抽象方法,它只有方法聲明,而沒有具體的方法體。子類 Circle 繼承了 Shape 并實現(xiàn)了 draw 方法的具體實現(xiàn)。


#### 接口中的方法:


在 Java 中,接口是一種特殊的引用類型,它**只包含抽象方法的聲明**,而沒有實現(xiàn)。所有接口中的方法都是隱式地抽象的,不需要加上 abstract 關鍵字。


示例:


```java

interface MathOperation {

? ? int operate(int a, int b); // 接口中的抽象方法,沒有方法體

}


public class InterfaceExample {

? ? public static void main(String[] args) {

? ? ? ? MathOperation addition = (a, b) -> a + b;

? ? ? ? int result = addition.operate(5, 3);

? ? ? ? System.out.println("Result: " + result);

? ? }

}


```


在這個示例中,MathOperation 接口中的 operate 方法是一個抽象方法,只有方法聲明,沒有具體實現(xiàn)。


所以,在特定的編程概念中,的確存在方法沒有方法體的情況,這使得這些概念更具有靈活性和可擴展性。



### 14-1 方法的重載

重載就是在一個類中,有相同的函數(shù)名稱,但形參不同(數(shù)量、質(zhì)量 )的函數(shù)。


#### 應用:類中構(gòu)造器的重載!用于類的初始化

在你的代碼中,定義了三個類:SuperType、SubType 和 Main。SuperType 是基類,SubType 是派生類,而 Main 是包含 main 方法的類。下面來解釋一下這些類的行為和輸出。


```java

public class SuperType {

? ? public SuperType() {

? ? ? ? System.out.print("super");

? ? }

}


public class SubType extends SuperType {

? ? public SubType() {

? ? ? ? System.out.print("sub");

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? SubType st = new SubType();

? ? }

}

//supersub

```


```java

// 定義基類 SuperType

public class SuperType {

? ? // 基類的構(gòu)造函數(shù)

? ? public SuperType() {

? ? ? ? // 輸出 "super"

? ? ? ? System.out.print("super");

? ? }

}


// 定義派生類 SubType,繼承自 SuperType

public class SubType extends SuperType {

? ? // 派生類的構(gòu)造函數(shù)

? ? public SubType() {

? ? ? ? // 輸出 "sub"

? ? ? ? System.out.print("sub");

? ? }

}


// 定義包含 main 方法的類 Main

public class Main {

? ? // 主方法

? ? public static void main(String[] args) {

? ? ? ? // 創(chuàng)建 SubType 類的實例 st

? ? ? ? SubType st = new SubType();

? ? }

}

? ??

```

![](media/16917251481696/16918885095646.jpg)


在這份代碼中,定義了三個類:SuperType、SubType 和 Main。SuperType 是基類,SubType 是派生類,Main 包含 main 方法。


public class SuperType {:定義基類 SuperType。

**public SuperType() {:基類的構(gòu)造函數(shù),它在對象被創(chuàng)建時自動調(diào)用**

System.out.print("super");:輸出 "super"。

public class SubType extends SuperType {:定義派生類 SubType,它繼承自 SuperType。

public SubType() {:派生類的構(gòu)造函數(shù)。

System.out.print("sub");:輸出 "sub"。

public class Main {:定義包含 main 方法的類 Main。

public static void main(String[] args) {:main 方法,程序的入口。

SubType st = new SubType();:創(chuàng)建 SubType 類的實例 st,這會觸發(fā)構(gòu)造函數(shù)的調(diào)用。


> 在這個代碼中,當你創(chuàng)建一個 SubType 的實例時,會觸發(fā)構(gòu)造函數(shù)的調(diào)用。

> 首先,基類的構(gòu)造函數(shù) SuperType() 被調(diào)用,

> 然后派生類的構(gòu)造函數(shù) SubType() 被調(diào)用。


### 14-2 在創(chuàng)建子類的實例時,構(gòu)造器會按照繼承鏈的順序被逐個調(diào)用。

> 當創(chuàng)建子類的實例時,會自動調(diào)用父類的構(gòu)造器和子類的構(gòu)造器。

> 這是因為子類繼承了父類的屬性和方法,包括構(gòu)造器。

> 在創(chuàng)建子類的實例時,構(gòu)造器會按照**繼承鏈的順序**被逐個調(diào)用。

>?

```java

public class Parent {

? ? public Parent() {

? ? ? ? System.out.println("Parent constructor");

? ? }

}


public class Child extends Parent {

? ? public Child() {

? ? ? ? System.out.println("Child constructor");

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? Child child = new Child();

? ? }

}

```


在這個例子中,當你創(chuàng)建 Child 類的實例 child 時,會自動調(diào)用父類 Parent 的構(gòu)造器,然后再調(diào)用子類 Child 的構(gòu)造器。運行這個程序,你會看到輸出:


```java

Parent constructor

Child constructor


```


這表明構(gòu)造器的調(diào)用順序是**先調(diào)用父類的構(gòu)造器**,然后再調(diào)用子類的構(gòu)造器。這確保了在創(chuàng)建子類的實例時,**父類的初始化代碼也能得到執(zhí)行**。


需要注意的是,**如果你沒有顯式地在子類的構(gòu)造器中調(diào)用父類的構(gòu)造器,Java 會默認調(diào)用父類的無參構(gòu)造器(如果父類有無參構(gòu)造器)**。如果父類沒有無參構(gòu)造器,并且你沒有在子類構(gòu)造器中顯式地調(diào)用父類構(gòu)造器,那么會編譯錯誤。


***



### 14-3 顯式地調(diào)用父類構(gòu)造器



當你在子類的構(gòu)造器中顯式地調(diào)用父類的構(gòu)造器時,你可以使用關鍵字 super 來實現(xiàn)。使用 super 關鍵字,你可以在子類的構(gòu)造器中調(diào)用父類的構(gòu)造器。這通常用于在子類構(gòu)造器中執(zhí)行父類的初始化工作。


以下是一個示例,展示了如何使用 super 關鍵字顯式地調(diào)用父類的構(gòu)造器:



```java

public class Parent {

? ? public Parent() {

? ? ? ? System.out.println("Parent constructor");

? ? }

}


public class Child extends Parent {

? ? public Child() {

? ? ? ? super(); // 調(diào)用父類的構(gòu)造器

? ? ? ? System.out.println("Child constructor");

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? Child child = new Child();

? ? }

}


```


```java

Parent constructor

Child constructor


```


這表明在子類構(gòu)造器中使用 super() 調(diào)用父類構(gòu)造器時,先執(zhí)行父類構(gòu)造器的初始化代碼,然后再執(zhí)行子類構(gòu)造器的初始化代碼。


需要注意的是,如果你在子類的構(gòu)造器中沒有顯式地使用 super() 調(diào)用父類構(gòu)造器,Java 會自動隱式地調(diào)用父類的無參構(gòu)造器(如果存在)。如果父類沒有無參構(gòu)造器,你需要在子類構(gòu)造器中顯式地調(diào)用父類的某個有參構(gòu)造器。






***



讓我用一個簡單的示例來說明這個過程:


運行 Main 類的 main 方法,輸出將是:


supersub

解釋:


當你創(chuàng)建 SubType 的實例時,它的構(gòu)造函數(shù) SubType() 被調(diào)用。

在 SubType 的構(gòu)造函數(shù)中,會先調(diào)用基類 SuperType 的構(gòu)造函數(shù) SuperType(),輸出 "super"。

接著,派生類 SubType 的構(gòu)造函數(shù)繼續(xù)執(zhí)行,輸出 "sub"。

所以,最終的輸出是 "super" 和 "sub",合并成了 "supersub"。



***


??

構(gòu)造函數(shù)(Constructor)是一種特殊類型的方法,在創(chuàng)建一個類的實例(對象)時被調(diào)用。它主要用于初始化對象的狀態(tài)和屬性。構(gòu)造函數(shù)具有與類同名的名稱,并且沒有顯式的返回類型。在 Java 中,構(gòu)造函數(shù)的主要特點包括:


- 與類同名: 構(gòu)造函數(shù)的名稱必須與所在類的名稱完全一致。

- 沒有返回類型: 構(gòu)造函數(shù)沒有返回類型,包括 void,因為它們的主要目的是創(chuàng)建對象而不是返回值。

- 自動調(diào)用: 構(gòu)造函數(shù)在創(chuàng)建對象時自動調(diào)用。當使用 new 關鍵字創(chuàng)建類的新實例時,相應的構(gòu)造函數(shù)會被調(diào)用。

- 可以重載: 與其他方法一樣,構(gòu)造函數(shù)也可以被重載,即在同一個類中可以定義多個不同參數(shù)列表的構(gòu)造函數(shù)。

- 隱式默認構(gòu)造函數(shù): 如果沒有顯式地為類定義構(gòu)造函數(shù),Java 會提供一個默認的無參構(gòu)造函數(shù),它不執(zhí)行任何特定的初始化操作。但是,如果你定義了任何構(gòu)造函數(shù),包括有參構(gòu)造函數(shù),那么默認的無參構(gòu)造函數(shù)就不會再自動生成。


例如,以下是一個簡單的類和構(gòu)造函數(shù)的示例:


構(gòu)造器說白了就是一個方法,所以它和普通的方法一樣也可以做方法重載,換句話說就是構(gòu)造器的重載。和方法重載一樣構(gòu)造器重載就是多個一樣名字參數(shù)類型和參數(shù)的個數(shù)不同的多個構(gòu)造器。構(gòu)造器也叫構(gòu)造方法(constructor), 用于對象初始化. 構(gòu)造器是一個創(chuàng)建對象時被自動創(chuàng)建的特殊方法,目的是對象的初始化.

```java

class Person {

? ? String name;

? ? int age;


? ? // 無參構(gòu)造器

? ? public Person() {

? ? ? ? name = "Unknown";

? ? ? ? age = 0;

? ? }


? ? // 帶參數(shù)構(gòu)造器

? ? public Person(String n, int a) {

? ? ? ? name = n;

? ? ? ? age = a;

? ? }


? ? // 方法用于輸出信息

? ? public void displayInfo() {

? ? ? ? System.out.println("Name: " + name + ", Age: " + age);

? ? }

}


public class ConstructorExample {

? ? public static void main(String[] args) {

? ? ? ? Person person1 = new Person();? // 使用無參構(gòu)造器

? ? ? ? person1.displayInfo();? // 輸出: Name: Unknown, Age: 0


? ? ? ? Person person2 = new Person("Alice", 25);? // 使用帶參數(shù)構(gòu)造器

? ? ? ? person2.displayInfo();? // 輸出: Name: Alice, Age: 25

? ? }

}


```



再來一個示例:


```java

// 定義基類 Animal

public class Animal {

? ? public int age; // 定義屬性 age,用于存儲年齡


? ? // 基類的有參構(gòu)造函數(shù),接受一個 age 參數(shù)

? ? public Animal(int age) {

? ? ? ? this.age = age; // 將傳入的 age 參數(shù)賦值給屬性

? ? }


? ? // 基類的無參構(gòu)造函數(shù)

? ? public Animal() {

? ? }

}


// 定義派生類 Person,繼承自 Animal

public class Person extends Animal {

? ? // 派生類的構(gòu)造函數(shù),接受一個 age 參數(shù)

? ? public Person(int age) {

? ? ? ? super(age); // 調(diào)用父類的有參構(gòu)造函數(shù),傳遞 age 參數(shù)到 Animal 的構(gòu)造函數(shù)

? ? }

}


// 主類 Main

public class Main {

? ? public static void main(String[] args) {

? ? ? ? Person p = new Person(10); // 創(chuàng)建一個 Person 對象,傳入年齡 10

? ? ? ? System.out.println(p.age); // 輸出對象的年齡屬性值,應該是 10

? ? }

}


//輸出 0?

```

> 核心:這里? Person(10)? 并未傳到Animal中去。

### 14-4 從子類傳參數(shù)到父類:? super(age);

? ? ? ? super(age); // 調(diào)用父類的有參構(gòu)造函數(shù),傳遞 age 參數(shù)


>通過 super(age) 調(diào)用了父類 Animal 的有參構(gòu)造函數(shù),將傳入的 age 參數(shù)正確地傳遞到了基類的構(gòu)造函數(shù)中,從而初始化了 age 屬性。



盡量用簡單的語言解釋了每行代碼的作用:


1. 定義基類 Animal。

2. 定義一個整數(shù)類型的屬性 age 用于存儲年齡。

3. 基類的有參構(gòu)造函數(shù),接受一個 age 參數(shù),并將傳入的值賦給屬性。

4. 基類的無參構(gòu)造函數(shù)。


5. 定義派生類 Person,繼承自 Animal。

6. 派生類的構(gòu)造函數(shù),接受一個 age 參數(shù)。

7. 在派生類的構(gòu)造函數(shù)中,使用 super() 調(diào)用父類的無參構(gòu)造函數(shù)(默認調(diào)用)。



1. 主類 Main。

2. 主方法 main。

3. 創(chuàng)建一個 Person 對象 p,傳入年齡值 10。

4. 輸出 p 對象的 age 屬性值,默認為 0。

5. 最終輸出結(jié)果為 0,因為在 Person 類的構(gòu)造函數(shù)中,雖然調(diào)用了父類的構(gòu)造函數(shù),但沒有顯式地傳遞傳入的 age 參數(shù),所以父類的構(gòu)造函數(shù)會將 age 設置為默認值 0。?



### 15 方法的聲明不能嵌套!!方法中不能在聲明方法??


在大多數(shù)編程語言中,包括 Java,方法(函數(shù))的聲明不能嵌套在其他方法內(nèi)部,也不能在一個方法中再次聲明另一個方法。**方法應該在類的作用域中進行聲明**,而不是在其他方法的內(nèi)部。


這是因為方法的聲明和定義通常用于在類級別上定義一種行為,而不是在方法內(nèi)部定義新的方法。在方法內(nèi)部聲明方法會導致代碼結(jié)構(gòu)混亂,并且可讀性會大大降低。


? ? 以下是一個示例,展示了在 Java 中不允許在方法內(nèi)部嵌套聲明方法:


```java

public class NestedMethodExample {

? ? public void outerMethod() {

? ? ? ? // 這里是外部方法的代碼

? ? ? ? // 不能在外部方法內(nèi)部聲明新的方法


? ? ? ? // 以下是錯誤的示例

? ? ? ? /*

? ? ? ? public void innerMethod() {

? ? ? ? ? ? // 這里是內(nèi)部方法的代碼

? ? ? ? }

? ? ? ? */

? ? }


? ? public static void main(String[] args) {

? ? ? ? NestedMethodExample example = new NestedMethodExample();

? ? ? ? example.outerMethod();

? ? }

}


```




#### 插播復習方法的定義:

修飾符 返回值類型 方法名(參數(shù)類型 參數(shù)名){

方法體

return 返回值;

}


調(diào)用方法:對象名.方法名(實參列表)


### 16 雕蟲小技 bug富含蛋白質(zhì) 奇文共賞

來看一段錯誤代碼:

```java

?package run;

? ?public class Main? {

? ? public static void main(String[] args) {

? ? int result = add(10,20);

? ? System.out.println(result);

? ? }

? ? public static void add(int num1,int num2){

? ? int result=num1 + num2;?

? ? }

? ?}

```




直接編譯不通過。

原因:

?add 方法中計算的 result 變量沒有返回值,因此在 main 方法中的 result 變量沒有得到正確的值。

?

?要使代碼正確運行,需要在 add 方法中返回計算結(jié)果。

?需要1? 修改 void 為 int 返回int類型的值?

?2? return result;??

? 以下是修正后的代碼:

??

??

```java

public class Main {

? ? public static void main(String[] args) {

? ? ? ? int result = add(10, 20);

? ? ? ? System.out.println(result);

? ? }


? ? public static int add(int num1, int num2) {

? ? ? ? int result = num1 + num2;

? ? ? ? return result; // 返回計算結(jié)果

? ? }

}


```


### 17 return new Integer(a+b);


```java

public class Main {

? ? public static void main(String[] args) {

? ? ? ? int a = 20;

? ? ? ? String b = "10";

? ? ? ? Integer result = Integer.valueOf(a + b);

? ? ? ? System.out.println(result); // 輸出:2010

? ? }

}


```

是一個用于創(chuàng)建一個新的 Integer 對象,并將**兩個整數(shù)相加后的結(jié)果作為其值**的操作。這種操作在一些特定情況下是有用的,但需要注意的是,從 Java 9 開始,這種用法不再推薦使用。

```java

public class IntegerExample {

? ? public static void main(String[] args) {

? ? ? ? Integer num1 = 10;

? ? ? ? Integer num2 = 10;


? ? ? ? System.out.println(num1 == num2); // 輸出 true,因為在范圍內(nèi)的整數(shù)值會共享對象

? ? }

}


```




### 18 花式重載

```java

package com.zhangyy.opp;





import java.util.Scanner;

public class Demo01? {

? ? public static void main(String[] args) {

? ? ? ? int a = 20;

? ? ? ? String b = "10";

? ? ? ? int c = method1(a, b);

? ? ? ? System.out.println(c);

? ? ? ? System.out.println(method1(b,c));

? ? ? ? System.out.println(method1(b,method1(a,b)));;

? ? }

? ? public static int method1(int a,String b){

? ? ? ? return new Integer(a+b);


? ? }


? ? public static String method1(String a,int b){

? ? ? ? return b+a;

? ? }

}


/*

2010

201010

201010

*/

```



### 19 package關鍵字放在import關鍵字前面?


在 Java 代碼中,package 關鍵字應該放在 import 關鍵字之前。package 用于定義代碼的包名,而 import 用于導入其他包中的類或接口,因此它們在代碼的結(jié)構(gòu)中是有順序的。


正確的代碼結(jié)構(gòu)應該是這樣的:

```java

package com.example.mypackage; // 包名放在最前面


import java.util.ArrayList; // 導入語句緊隨其后


public class MyClass {

? ? // 類的定義部分

}


```


### 20 函數(shù)的化簡順序是什么

函數(shù)的化簡順序通常遵循以下兩個基本原則:從內(nèi)到外,從左到右。這兩個原則有助于使代碼更加清晰、模塊化和易于閱讀。讓我為你解釋一下這兩個原則的含義:


#### 從內(nèi)到外:


這個原則表示,在一個函數(shù)調(diào)用鏈中,首先處理內(nèi)部的函數(shù)調(diào)用,然后將結(jié)果傳遞給外部的函數(shù)調(diào)用。這種方式確保中間步驟的結(jié)果可以無縫地傳遞給后續(xù)步驟,從而形成一個完整的處理過程。這有助于保持代碼的一致性,同時也使代碼的邏輯更容易理解。


#### 從左到右:


這個原則表示,在一個函數(shù)調(diào)用鏈中,函數(shù)的調(diào)用順序是從左到右的。也就是說,先調(diào)用最左邊的函數(shù),然后將其結(jié)果傳遞給下一個函數(shù),以此類推,最終得到最右邊函數(shù)的結(jié)果。這樣的順序讓代碼更加具有邏輯性,讓人能夠更容易地跟隨代碼的執(zhí)行過程。


這兩個原則的應用可以使代碼更加緊湊、易于維護和易于理解。它們是函數(shù)式編程的核心思想,被廣泛應用于一些函數(shù)式編程語言和范式中,如 Haskell、Scala、Clojure 等。


### 21 main方法? 頭


main() 方法的頭定義可以根據(jù)情況任意更改。雖然 main() 方法的標準定義是 public static void main(String[] args),但在 Java 5 之后,方法的參數(shù)名稱 args 可以更改為其他有效的標識符,只要保持參數(shù)類型和順序不變。




一個類可以沒有 main() 方法。main() 方法是 Java 程序的入口點,但不是所有的類都需要定義 main() 方法。只有作為程序入口的類需要定義 main() 方法。


main() 方法并不一定需要放在公共類中。雖然 main() 方法通常在公共類中,但這不是必須的。main() 方法可以在非公共類中定義,只要程序的入口點位于公共類中即可。



不是所有對象的創(chuàng)建都必須放在 main() 方法中。main() 方法通常用于啟動程序,并在程序中創(chuàng)建所需的對象。但是,并不是所有的對象都必須在 main() 方法中創(chuàng)建。對象可以在程序的其他地方創(chuàng)建,取決于程序的結(jié)構(gòu)和邏輯。


### 22 用字符串 示例? == 嚴 引用對象內(nèi)存地址 和equals 內(nèi)容即可



```java


public class StringComparisonExample {

? ? public static void main(String[] args) {

? ? ? ? String str1 = new String("hello");

? ? ? ? String str2 = new String("hello");

? ? ? ? String str3 = str1; // 指向同一個對象


? ? ? ? System.out.println("Using ==:");

? ? ? ? System.out.println(str1 == str2); // 輸出 false,因為它們引用的是不同的對象

? ? ? ? System.out.println(str1 == str3); // 輸出 true,因為它們引用的是同一個對象


? ? ? ? System.out.println("\nUsing equals:");

? ? ? ? System.out.println(str1.equals(str2)); // 輸出 true,因為 equals 比較的是內(nèi)容

? ? ? ? System.out.println(str1.equals(str3)); // 輸出 true,因為 equals 比較的是內(nèi)容

? ? }

}


```


### 23 Java中


#### 1 引用類型初始化后未賦值之前的值為null


#### 2 基本數(shù)據(jù)類型?

byte、short、int、long、boolean、char、float、double

這里要注意char類型**初始化之后的默認值為空白null**(注意:不是空格)


|類型? |初始化后的默認值 |

|--|--|

boolean? ? ?|? ?false

char? ? ? ? ?|? ? ? '/uoooo'(null)

byte? ? ? ? ? |? ? ?(byte)0

short? ? ? ? ? |? ? (short)0

int? ? ? ? ? ? |? ? ? ?0

long? ? ? ? ? |? ? ? 0L

float? ? ? ? ? ? |? ? 0.0f

double? ? ? ? ? |? 0.0d




```java

import java.util.Arrays;

public class Test {

public static byte byte1;

public static short s;

public static int i;

public static long l;

public static char c;

public static boolean boolean1;

public static float f;

public static double d;

@org.junit.Test

public void test() throws Exception {

System.out.println("byte:" + byte1); //byte:0

System.out.println("short:" + s); //s:0

System.out.println("int:" + i); //i:0

System.out.println("long:" + l); //l:0

System.out.println("char:" + c); //char:

System.out.println("boolean:" + boolean1); //boolean:false

System.out.println("float:" + f); //l:0.0

System.out.println("double:" + d); //l:0.0

}

}




```

#### 這里要注意char類型**初始化之后的默認值為空白null**(注意:不是空格)


### 24 接23 空字符串:


空字符串是一個長度為 0 的字符串,表示沒有字符的字符串。在 Java 中,可以使用兩種方式表示空字符串:


1 通過字面值:String emptyString = "";

2 使用 String 類的構(gòu)造方法:String emptyString = new String();

```java

String emptyString1 = ""; // 通過字面值創(chuàng)建空字符串

String emptyString2 = new String(); // 使用構(gòu)造方法創(chuàng)建空字符串


System.out.println(emptyString1.isEmpty()); // 輸出 true,因為長度為 0

System.out.println(emptyString2.isEmpty()); // 輸出 true,因為長度為 0


```



```java

import java.util.Scanner;

public class Demo01? {

? ? public static void main(String[] args) {


? ? ? ? String emptyString = new String(); // 使用構(gòu)造方法創(chuàng)建空字符串

? ? ? ? System.out.println(emptyString);

? ? }


}


```

![](media/16917251481696/16918305246084.jpg)


###? 25? ?class Person{ public Dog pet = new Dog(); }默認每人都有狗

```java

class Person {

? ? public int age;

? ? public String name;

? ? public Dog pet = new Dog(); // 默認的寵物狗


? ? // 其他類成員和方法

}


```


定義了一個名為 Person 的類,該類有以下成員:


public int age;:這是一個公共成員變量,表示人的年齡,可以在類的外部訪問和修改。

public String name;:這是一個公共成員變量,表示人的姓名,也可以在類的外部訪問和修改。

public Dog pet = new Dog();:這是一個公共成員變量,表示人的寵物。它使用 new Dog() 初始化為一個 Dog 對象,意味著每個 Person 對象都會有一個默認的寵物狗。



#### 法外張三 和 旺財?shù)目鞓飞睿?/p>


```java

? ? package com.zhangyy.opp;


? ? // Dog 類表示寵物狗

? ? class Dog {

? ? ? ? public String name;


? ? ? ? // 構(gòu)造方法,用于初始化寵物狗的名字

? ? ? ? public Dog() {

? ? ? ? ? ? this.name = "旺財"; // 默認名字為“旺財”

? ? ? ? }


? ? ? ? // 狗叫的方法

? ? ? ? public void bark() {

? ? ? ? ? ? System.out.println(name + ":汪汪汪!");

? ? ? ? }

? ? }


? ? // Person 類表示人

? ? class Person {

? ? ? ? public int age;

? ? ? ? public String name;

? ? ? ? public Dog pet = new Dog(); // 默認的寵物狗


? ? ? ? // 構(gòu)造方法,用于初始化人的年齡和名字

? ? ? ? public Person(int age, String name) {

? ? ? ? ? ? this.age = age;

? ? ? ? ? ? this.name = name;

? ? ? ? }


? ? ? ? // 與寵物狗一起玩耍的方法

? ? ? ? public void playWithPet() {

? ? ? ? ? ? System.out.println(name + " 和 " + pet.name + " 正在一起玩耍!");

? ? ? ? ? ? pet.bark();

? ? ? ? }


? ? ? ? // 自我介紹的方法

? ? ? ? public void introduce() {

? ? ? ? ? ? System.out.println("我是 " + name + ",今年 " + age + " 歲,我有一只叫做 " + pet.name + " 的寵物狗。");

? ? ? ? }

? ? }


? ? // 主類 HappyLifeScript

? ? public class HappySugerLife {

? ? ? ? public static void main(String[] args) {

? ? ? ? ? ? // 創(chuàng)建一個名為“張三”的人,并設置年齡為 27

? ? ? ? ? ? Person person = new Person(27, "張三");


? ? ? ? ? ? // 調(diào)用自我介紹方法

? ? ? ? ? ? person.introduce();


? ? ? ? ? ? // 調(diào)用與寵物狗一起玩耍的方法

? ? ? ? ? ? person.playWithPet();

? ? ? ? }

? ? }


```


### 25 裝箱(Boxing)和拆箱(Unboxing)

裝箱(Boxing)和拆箱(Unboxing)是 Java 中用于基本數(shù)據(jù)類型和對應的包裝類之間轉(zhuǎn)換的過程。

#### 裝箱(Boxing):


裝箱是將基本數(shù)據(jù)類型轉(zhuǎn)換為對應的包裝類的過程。在裝箱過程中,基本數(shù)據(jù)類型的值被封裝到包裝類的實例中。Java 提供了自動裝箱和顯式裝箱兩種方式。


自動裝箱示例:

```java

int intValue = 42;

Integer integerValue = intValue; // 自動裝箱


```


顯式裝箱示例:


```java

int intValue = 42;

Integer integerValue = Integer.valueOf(intValue); // 顯式裝箱


```

拆箱(Unboxing):


拆箱是將包裝類中封裝的基本數(shù)據(jù)類型值提取出來的過程。在拆箱過程中,包裝類的實例被轉(zhuǎn)換為基本數(shù)據(jù)類型的值。Java 提供了自動拆箱和顯式拆箱兩種方式。


自動拆箱示例:


```java

Integer integerValue = 42;

int intValue = integerValue; // 自動拆箱


```

顯式拆箱示例:


```java

Integer integerValue = Integer.valueOf(42);

int intValue = integerValue.intValue(); // 顯式拆箱


```


### 26 方法中參數(shù)聲明父類時,可以傳入子類對象,被稱為"多態(tài)性"。



是的,這是面向?qū)ο缶幊讨械囊粋€重要特性,被稱為"多態(tài)性"。

在 Java 中,可以將一個子類的實例傳遞給一個方法,該方法的參數(shù)類型聲明為其父類類型。這個特性允許你在**不知道具體子類類型**的情況下操作對象,從而增加了代碼的靈活性和可擴展性。


這種行為基于繼承關系,允許你在一個通用的父類上進行操作,而無需關心實際傳遞的是哪個子類。這是通過多態(tài)性實現(xiàn)的,多態(tài)性是面向?qū)ο缶幊痰暮诵母拍钪弧?/p>


例如,假設你有一個基類 Animal 和兩個子類 Dog 和 Cat:

```java

class Animal { }

class Dog extends Animal { }

class Cat extends Animal { }


```

你可以這樣調(diào)用一個方法并傳遞不同子類的實例:


```java

public void processAnimal(Animal animal) {

? ? // 在這里操作 Animal 類型的對象

}


public static void main(String[] args) {

? ? Animal dog = new Dog();

? ? Animal cat = new Cat();


? ? processAnimal(dog); // 可以傳入 Dog 類型的對象

? ? processAnimal(cat); // 可以傳入 Cat 類型的對象

}


```


### 27 java.lang和java.util包

這兩個包,java.lang和java.util,是Java編程語言的核心包之一,它們包含了許多常用的類和工具,用于支持各種基本的編程任務和操作。


#### java.lang包:

這是Java語言的核心包,其中包含了一些基本的類和對象,它們在Java程序中無需顯式導入,因為它們在每個Java程序中都是**默認可用**的。這些類包括:

Object:所有類的超類,提供了一些基本方法如equals()、hashCode()和toString()。

String:用于操作字符串的類,提供了豐富的字符串操作方法。

System:提供與系統(tǒng)相關的方法和字段,如標準輸入輸出流等。

Math:提供基本的數(shù)學運算方法,如平方根、三角函數(shù)等。

Integer、Double、Boolean 等基本數(shù)據(jù)類型的包裝類。

Thread:用于多線程編程的類,包括線程的創(chuàng)建、同步等操作。

#### java.util包:

這個包包含了一些常用的工具類,用于處理集合、日期、時間、隨機數(shù)等。一些重要的類和接口包括:

ArrayList、LinkedList:可變大小的數(shù)組和鏈表實現(xiàn)的集合類。

HashMap、LinkedHashMap、TreeMap:用于存儲鍵值對的映射表實現(xiàn)。

HashSet、LinkedHashSet、TreeSet:用于存儲不重復元素的集合實現(xiàn)。

Date、Calendar:用于處理日期和時間。

Random:生成隨機數(shù)的類。

Scanner:用于從標準輸入讀取數(shù)據(jù)的類。

這些包提供了Java編程中常用的核心功能。如果你想要在代碼中使用這些包中的類和方法,只需在代碼的開頭使用import語句導入所需的類即可,例如:



```java


import java.util.ArrayList;

import java.util.HashMap;


public class MyClass {

? ? public static void main(String[] args) {

? ? ? ? ArrayList<String> list = new ArrayList<>();

? ? ? ? HashMap<String, Integer> map = new HashMap<>();

? ? ? ? // 使用list和map進行操作

? ? }

}


```

### 28 File類 (java.io.File):

?File類在java.io包下面??

?FileInputStream類在java.io包下面??


File類和FileInputStream類都是位于Java編程語言的java.io包下面的核心類,用于文件和輸入流的操作。


#### File類 (java.io.File):

File類用于表示文件或目錄的抽象路徑名,它提供了一些方法用于操作文件和目錄的屬性、路徑等。通過File類,您可以創(chuàng)建、刪除、重命名文件或目錄,查詢路徑信息等。以下是一些File類的常見用法:

```java


import java.io.File;


public class FileExample {

? ? public static void main(String[] args) {

? ? ? ? // 創(chuàng)建File對象表示文件或目錄

? ? ? ? File file = new File("example.txt");

? ? ? ??

? ? ? ? // 查詢文件或目錄的屬性

? ? ? ? System.out.println("Is file exists: " + file.exists());

? ? ? ? System.out.println("Is it a directory: " + file.isDirectory());

? ? ? ? System.out.println("Absolute path: " + file.getAbsolutePath());

? ? ? ??

? ? ? ? // 創(chuàng)建新目錄

? ? ? ? File directory = new File("myDirectory");

? ? ? ? directory.mkdir();

? ? ? ??

? ? ? ? // 刪除文件或目錄

? ? ? ? file.delete();

? ? }

}

```




#### FileInputStream類 (java.io.FileInputStream):

FileInputStream類用于從文件中讀取字節(jié)數(shù)據(jù),它是輸入流的一種。您可以使用FileInputStream來打開文件并逐個字節(jié)地讀取其中的內(nèi)容。以下是一個簡單的示例:

```java


import java.io.FileInputStream;

import java.io.IOException;


public class FileInputStreamExample {

? ? public static void main(String[] args) {

? ? ? ? try (FileInputStream fis = new FileInputStream("example.txt")) {

? ? ? ? ? ? int byteRead;

? ? ? ? ? ? while ((byteRead = fis.read()) != -1) {

? ? ? ? ? ? ? ? System.out.print((char) byteRead); // 將字節(jié)轉(zhuǎn)換為字符輸出

? ? ? ? ? ? }

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? }

}

```

需要注意的是,在使用這些類時,應該處理可能拋出的異常,如IOException。另外,在結(jié)束使用后,應該關閉文件流以釋放資源,這在上面的示例中通過try-with-resources語句實現(xiàn)。



### 29 包 package?

a編譯通過:

```java

package aa;

public class A { }


package aa.bb;

import aa.A;

public class B {

? ? public A a = new A();

}


package bb;

import aa.bb.B;

public class C {

? ? public B b = new B();

}


```

- 每個類都在獨立的源文件中,沒有多個包聲明或類定義在同一個源文件中。

- 在類 B 中,通過 import aa.A; 導入了 A 類,因為它們在不同的包中,但是代碼仍然是合法的。

- 類 C 導入了類 B 并創(chuàng)建了 B 的實例,也沒有問題。



b編譯不通過

```java

package aa;

public class A { }


package aa.bb;

public class B {

? ? public A a = new A();

}


package bb;

import aa.bb.B;

public class C {

? ? public B b = new B();

}


```



### 30 如何避免 import 與類的使用上,編譯錯誤

避免import語句與類的使用上的編譯錯誤需要遵循一些Java的組織和語法規(guī)則。下面是一些方法來確保正確使用import語句和類,從而避免編譯錯誤:


1. 正確的包聲明: 確保每個源文件的包聲明與其所在的文件夾結(jié)構(gòu)匹配。包聲明在源文件的開頭使用package關鍵字指定。例如,如果文件位于包com.example下,那么包聲明應該是package com.example;。

2. 正確的類定義: 確保每個源文件中只有一個公共類,并且類的名稱與文件名相匹配。公共類的名稱應該與文件名完全一致。

3. 使用完整的類名: 如果您在一個類中使用不在同一個包中的類,可以使用完整的類名(包括包名)。這樣,您不必使用import語句。例如,java.util.ArrayList而不是import java.util.ArrayList;。

4. 只導入所需的類: 只導入您實際需要的類,而不是導入整個包。這可以避免可能的命名沖突。

5. 使用IDE的自動導入功能: 集成開發(fā)環(huán)境(IDE)通常會自動為您添加import語句,確保您在使用類時能夠正確地導入。IDE還可以幫助您查找和修復可能的導入錯誤。

6. 遵循命名規(guī)范: 命名規(guī)范有助于避免名稱沖突。按照Java的命名約定來為包、類和變量選擇有意義的名稱。

7. 檢查錯誤消息: 編譯器會生成錯誤和警告消息,指出您的代碼中的問題。仔細閱讀這些消息,以便能夠識別和修復問題。

8. 檢查包路徑: 當您使用不在同一包中的類時,確保包路徑是正確的。如果包路徑不正確,編譯器將無法找到類。

檢查依賴關系: 如果類依賴于其他類,確保這些依賴項也正確地導入并在路徑中可用。

通過遵循這些準則,您可以減少導入和類使用方面的編譯錯誤,并且更好地組織您的Java代碼。




用簡單的代碼示例來解釋。假設我們有兩個包:com.example 和 com.example.animals,每個包下都有一個類。


1. 示例:正確使用import語句和類。


假設我們有以下文件結(jié)構(gòu):

```java

markdown

Copy code

com

? └── example

? ? ? ?└── MyClass.java

? ? ? ?└── animals

? ? ? ? ? ? └── Dog.java

現(xiàn)在,讓我們看一下如何在 MyClass.java 中正確使用 import 語句和類:

```




```java

// MyClass.java

package com.example;


import com.example.animals.Dog;


public class MyClass {

? ? public static void main(String[] args) {

? ? ? ? Dog dog = new Dog();

? ? ? ? dog.bark();

? ? }

}

```

在這個示例中,我們在 MyClass.java 中使用了 import com.example.animals.Dog; 語句來導入 Dog 類,這樣我們可以在 MyClass 中使用它,而不需要寫完整的類路徑。


2. 示例:使用完整的類名。


如果您不想使用import語句,您可以直接使用完整的類名:


```java

Copy code

// MyClass.java

package com.example;


public class MyClass {

? ? public static void main(String[] args) {

? ? ? ? com.example.animals.Dog dog = new com.example.animals.Dog();

? ? ? ? dog.bark();

? ? }

}

```

在這個示例中,我們沒有使用 import 語句,而是直接在 MyClass 中使用了完整的類路徑來創(chuàng)建 Dog 類的實例。


這兩個示例演示了如何使用import語句和直接使用完整類名來避免編譯錯誤。通過這些方法,您可以更好地組織代碼,并確保它們在正確的包和類中運行。




###? default修飾符=>同包下的類可訪問/繼承,其他類可以繼承




### 31 @Data注解.? ?set get 方法? ?lombok包?

可以自動生成該類私有屬性的set get 方法?

?使用@Data注解,應導入lombok包?


@Data 注解是 Lombok 提供的一個注解,用于自動生成 Java 類的一些標準方法,如 toString()、equals()、hashCode(),以及私有屬性的 get 和 set 方法。這大大減少了重復編寫這些標準方法的工作。同時,@Data 也包括 @Getter、@Setter、@ToString 和 @EqualsAndHashCode 的功能。


關于 @Data 注解的使用和相關導入,請參考以下幾點:


導入 Lombok 包:

在使用 @Data 注解之前,確保您已經(jīng)導入了 Lombok 包,以便編譯器能夠識別和處理注解。您可以在項目的構(gòu)建工具中添加 Lombok 依賴,比如 Maven 或 Gradle。

自動生成 get 和 set 方法:

當您在類上使用 @Data 注解時,它將自動為類中的所有私有字段生成 get 和 set 方法。這樣,您不需要顯式編寫這些方法。

自動導入外部類:

@Data 注解本身不會自動導入類里引用的外部類。Java 在導入外部類方面仍然遵循常規(guī)的導入規(guī)則。如果您在類中引用了外部類,您仍需要使用標準的 import 語句來導入這些外部類。

導入 java.util 包:

與 @Data 注解本身無關,java.util 包是 Java 標準庫中的一個包,用于提供各種常用的工具類和集合類。您可以在使用 Java 標準庫中的類時,根據(jù)需要導入 java.util 包。

綜上所述,使用 @Data 注解可以讓您輕松地生成標準方法和私有屬性的 get 和 set 方法,但它不會自動導入外部類。同時,確保在使用 Lombok 注解之前導入了 Lombok 包。至于 java.util 包的導入,與 @Data 注解本身無關,而是與您在代碼中使用的具體類有關。


### public abstract class Person {}?



### 32 抽象類不一定需要包含抽象方法.


#### 抽象類:?

抽象類是**不能被實例化的類**,它可以包含抽象方法和非抽象方法。

抽象方法是一種沒有實現(xiàn)體的方法,它只有方法聲明,沒有方法體。

抽象類用于作為其他類的**基類**,它可以定義一些共享的屬性和方法,但可能需要子類來實現(xiàn)具體的方法邏輯。

#### 抽象方法:

?抽象方法是在抽象類中聲明的方法,但沒有提供實際的方法實現(xiàn)。子類繼承抽象類時,需要提供對抽象方法的具體實現(xiàn)。**抽象方法通常用來定義一個接口**要求繼承的子類**必須**提供特定的方法實現(xiàn)。

#### 所以,抽象類有兩種類型的方法:


抽象方法: 這些方法沒有實際的實現(xiàn),需要由子類提供具體實現(xiàn)。

非抽象方法: 這些方法在抽象類中有實際的實現(xiàn),子類可以直接繼承或者覆蓋。

以下是一個示例,展示了抽象類**不一定擁有抽象方法**:


```java

Copy code

abstract class Animal {

? ? String name;


? ? // 非抽象方法

? ? void eat() {

? ? ? ? System.out.println(name + " is eating");

? ? }

}


class Dog extends Animal {

? ? Dog(String name) {

? ? ? ? this.name = name;

? ? }

}


class Cat extends Animal {

? ? Cat(String name) {

? ? ? ? this.name = name;

? ? }

}


public class Main {

? ? public static void main(String[] args) {

? ? ? ? Dog dog = new Dog("Buddy");

? ? ? ? dog.eat();


? ? ? ? Cat cat = new Cat("Whiskers");

? ? ? ? cat.eat();

? ? }

}

```

在這個示例中,Animal 是一個抽象類,但它沒有抽象方法,而是擁有一個非抽象方法 eat()。Dog 和 Cat 類繼承自 Animal 類,可以直接繼承并使用 eat() 方法。這個示例說明了抽象類不一定需要擁有抽象方法,它可以包含具體實現(xiàn)的非抽象方法。


***


#### 抽象類的幾個實現(xiàn)的例子:


分析您提供的三個代碼示例:


```java


public abstract class Animal {

? ? public abstract void walk();

? ? public void eat(){}

}


class Person extends Animal {

? ? public void walk() {}

}

```

eat() 方法是一個非抽象方法,但它在 Animal 類中并沒有給出具體的方法體。這在 Java 中是合法的,因為非抽象方法可以有默認的實現(xiàn)。如果在子類中沒有覆蓋這個方法,它將繼續(xù)使用默認的空實現(xiàn)。在這個特定的示例中,Person 類并沒有為 eat() 方法提供覆蓋,因此它繼承了默認的空實現(xiàn)。


所以,eat() 方法在 Animal 類中的默認實現(xiàn)是一個空的方法體。這意味著如果在子類中沒有覆蓋這個方法,它會繼續(xù)使用**空的默認實現(xiàn)**。

***

```java

Copy code

public abstract class Animal {

? ? public abstract void walk();

? ? public void eat(){}

}


abstract class Person extends Animal {}

```繼承了抽象類的抽象?

在這個示例中,您同樣定義了一個抽象類 Animal,其中包含一個抽象方法 walk() 和一個非抽象方法 eat()。然后,您定義了一個名為 Person 的抽象類**它繼承自 Animal 類。因為 Person 類是抽象類,您不需要提供對 walk() 和 eat() 方法的具體實現(xiàn)。**

即示例中,Person 類是一個抽象類,繼承自 Animal 類,而且不需要提供對 walk() 和 eat() 方法的具體實現(xiàn),因為它是一個抽象類。



***

```java

public abstract class Animal {

? ? public abstract void walk();

? ? public void eat(){}

}


abstract class Person extends Animal {

? ? public void walk(){}

}

```

在這個示例中,與第一個示例類似,您定義了一個抽象類 Animal,其中包含一個抽象方法 walk() 和一個非抽象方法 eat()。然后,您定義了一個名為 Person 的抽象類,它繼承自 Animal 類,并實現(xiàn)了抽象方法 walk()。同樣地,Person 類沒有重寫 eat() 方法。


Person 抽象類繼承了 Animal 抽象類,并提供了對 walk() 方法的實現(xiàn),雖然該實現(xiàn){}為空。


這意味著繼承自 Person 類的具體子類不再需要提供 walk() 方法的實現(xiàn),因為 Person 抽象類已經(jīng)提供了一個空的默認實現(xiàn)。這個特性使得繼承層次中的具體子類可以選擇性地覆蓋 walk() 方法,或者直接使用來自 Person 類的默認實現(xiàn)。




總結(jié):

在這三個示例中,您都展示了抽象類 Animal 和抽象類 Person 的關系。在每個示例中,Animal 類都包含一個抽象方法 walk() 和一個非抽象方法 eat()。Person 類繼承自 Animal 類,并根據(jù)需要實現(xiàn)了抽象方法 walk()。Person 類可以是具體類,也可以是抽象類,取決于是否提供了對 walk() 方法的實際實現(xiàn)。




### 33? ?JAVA中接口中可以不定義方法,編譯不報錯; JAVA中接口中只能定義抽象方法。即 有{}方法體的 一律為錯。



?JAVA中接口中只能定義抽象方法?





# java查漏補缺系列_01_230813的評論 (共 條)

分享到微博請遵守國家法律
拜泉县| 博爱县| 军事| 珲春市| 噶尔县| 蒲城县| 云安县| 阳泉市| 巴马| 华池县| 永济市| 五原县| 涞水县| 邮箱| 栾川县| 龙州县| 常山县| 安乡县| 进贤县| 三穗县| 瑞金市| 衡东县| 竹山县| 达拉特旗| 峡江县| 额敏县| 木兰县| 新田县| 泰和县| 孝昌县| 新余市| 山阳县| 大埔县| 孙吴县| 偃师市| 应城市| 鄂托克前旗| 大洼县| 宣威市| 滨海县| 邯郸市|