# Java基礎(chǔ)知識與面試題整理(一)
@[toc]
----
----
## 垃圾回收機(jī)制
傳統(tǒng)C/C++等編程語言需要程序員顯示進(jìn)行垃圾回收草则,顯示進(jìn)行垃圾回收主要有以下兩個缺點(diǎn):
1. 程序忘記回收無用內(nèi)存,從而導(dǎo)致內(nèi)存泄漏,降低系統(tǒng)性能热鞍。
2. 程序錯誤地回收程序核心類庫的內(nèi)存召噩,從而導(dǎo)致系統(tǒng)崩潰父虑。
JAVA程序的內(nèi)存分配和回收都是由JRE在后臺自動進(jìn)行的该酗。JRE會負(fù)責(zé)回收那些不在使用的內(nèi)存,這種機(jī)制被稱為**垃圾回收**(Garbage Collection士嚎,簡稱**GC**)
通常JRE會提供一條超級線程來進(jìn)行檢測和控制,一般都是在`CPU空閑`或`內(nèi)存不足時`自動進(jìn)行垃圾回收悔叽,而程序員無法精準(zhǔn)控制垃圾回收的時間和順序莱衩。
Java語言規(guī)范沒有明確的說明JVM使用的是哪種垃圾回收算法,但任何垃圾回收算法一般要做兩件事: 1.`發(fā)現(xiàn)無用對象`娇澎;2.`回收被無用對象占據(jù)的內(nèi)存空間笨蚁,使該空間可以被程序再次使用`;
**垃圾回收特點(diǎn)**:
? - 垃圾回收機(jī)制的工作目標(biāo)是`回收無用對象的內(nèi)存空間`趟庄,這些內(nèi)存空間都是JVM`堆內(nèi)存`里的內(nèi)存空間括细,垃圾回收只能回收`內(nèi)存資源`,對其他物理資源戚啥,如數(shù)據(jù)庫連接奋单、磁盤IO等資源則無能為力;
? - 為了更快地讓垃圾回收機(jī)制回收那些不再使用的對象猫十,可以通過將`該對象的引用置為null`览濒,通過這種方式暗示垃圾回收機(jī)制可以回收該對象。
? - 垃圾回收發(fā)生的`不可預(yù)知性`:由于不同JVM才用了不同的垃圾回收機(jī)制和不同的垃圾回收算法拖云,因此它有可能是`定時發(fā)生`贷笛,有可能適當(dāng)`CPU空閑`時發(fā)生,也有可能是和原始垃圾回收一樣宙项,等到`內(nèi)存消耗出現(xiàn)極限`時發(fā)生乏苦,這些和垃圾回收機(jī)制的選擇和具體的設(shè)置都有關(guān)系。雖然程序員可以通過調(diào)用該對象的`finalize()`方法或`system.gc()`等方法來建議系統(tǒng)進(jìn)行垃圾回收尤筐,但這種調(diào)用僅僅是建議汇荐,依然不能`精確`控制垃圾回收機(jī)制的執(zhí)行。
? - 垃圾回收的精確性主要包括2個方面:一叔磷、垃圾回收機(jī)制能夠精確`標(biāo)記`活著的對象拢驾;二、垃圾回收器能夠精確地定位對象之間的`引用關(guān)系`改基。前者是完全回收所有廢棄對象的前提繁疤,否則就可能造成內(nèi)存泄漏咖为。而后者是實(shí)現(xiàn)`歸并`和`復(fù)制`等算法的必要條件,通過這種引用關(guān)系稠腊,可以保證所有對象都能被可靠地回收躁染,所有對象都能被重新分配,從而有效的`減少內(nèi)存碎片`的產(chǎn)生架忌。
? - 現(xiàn)在的JVM有多種不同的垃圾回收實(shí)現(xiàn)吞彤,每種回收機(jī)制因其算法差異,可能其表現(xiàn)各異叹放,有的當(dāng)垃圾回收開始時就`停止應(yīng)用程序的運(yùn)行`饰恕,有的當(dāng)垃圾回收運(yùn)行時,同時允許應(yīng)用程序的`線程`運(yùn)行井仰,還有的在同一時間垃圾回收`多線程`運(yùn)行埋嵌。
**特點(diǎn)(簡化版)**:
- 垃圾回收機(jī)制只負(fù)責(zé)回收`堆內(nèi)存`中的對象,不會回收任何物理資源俱恶。
- 程序無法精確控制垃圾回收的運(yùn)行雹嗦。
- 垃圾回收機(jī)制回收任何資源之前,總會調(diào)用它的`finalize`方法合是,該方法可能使對象重新復(fù)活了罪,從而導(dǎo)致垃圾回收機(jī)制取消回收。
> 在我們編寫Java程序時聪全,一個基本原則是:**對于不再需要的對象泊藕,不要引用它們**。
如果保持了對這些對象的引用荔烧,垃圾回收機(jī)制暫時不會回收該對象吱七,則會造成系統(tǒng)可用內(nèi)存越來越少,這時垃圾回收執(zhí)行的頻率也越高鹤竭,從而導(dǎo)致系統(tǒng)的性能下降踊餐。
### 對象在內(nèi)存中的狀態(tài)
- **激活狀態(tài)**:對象被創(chuàng)建后,有一個以上的引用變量引用它臀稚,這個對象就處于激活狀態(tài)吝岭,程序可通過引用變量來調(diào)用該對象的屬性和方法。
- **去活狀態(tài)**:如果程序中某個對象沒有任何引用變量引用它吧寺,這個對象就處于去活狀態(tài)窜管。這個狀態(tài)下,垃圾回收機(jī)制準(zhǔn)備回收該對象所占內(nèi)存稚机,再回收之前幕帆,系統(tǒng)會調(diào)用去活狀態(tài)對象的finalize方法進(jìn)行資源清理,如果在這個方法中重新又引用變量引用它赖条,那么這個對象變?yōu)榧せ顮顟B(tài)失乾,否則該對象進(jìn)入死亡狀態(tài)常熙。
- **死亡狀態(tài)**:當(dāng)對象沒有任何引用變量引用,且系統(tǒng)已經(jīng)調(diào)用過該對象的finalize方法碱茁,仍未變?yōu)榧せ顮顟B(tài)裸卫,那么該對象就處于死亡狀態(tài)。垃圾回收會回收處于死亡狀態(tài)的對象纽竣。
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190308123209893.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
**強(qiáng)制垃圾回收**:
- 調(diào)用System類的gc()靜態(tài)方法:`System.gc();`
- 調(diào)用Runtime對象的gc()實(shí)例方法:`Runtime.getRuntime().gc();`
這種強(qiáng)制只是通知系統(tǒng)進(jìn)行垃圾回收墓贿,系統(tǒng)是否會進(jìn)行垃圾回收不確定。
**finalize方法**
該方法定義在Object類中蜓氨,原型為:`protected void finalize() throws Throwable`
任何Java類都可以覆蓋finalize方法聋袋,在該方法中清理資源。
**finalize特點(diǎn)**:
- 永遠(yuǎn)不要主動調(diào)用某個對象的finalize方法语盈,該方法應(yīng)交給垃圾回收機(jī)制調(diào)用舱馅。
- finalize方法何時被調(diào)用,是否會調(diào)用具有`不確定性`刀荒。
- 當(dāng)JVM執(zhí)行去活對象方法時,可能使該對象或其他對象重新變?yōu)榧せ顮顟B(tài)
- 當(dāng)JVM執(zhí)行finalize出現(xiàn)了異常棘钞,垃圾回收機(jī)制`不會報(bào)異常`缠借,程序繼續(xù)執(zhí)行。
### 對象的軟宜猜、弱和虛引用
Java語言對象的引用有四種:
- ` 強(qiáng)應(yīng)用`:程序通過引用變量來操作實(shí)際對象泼返,被強(qiáng)引用的對象不能被垃圾回收機(jī)制回收。
- `軟引用(SoftReference)`:通過`SoftReference`類實(shí)現(xiàn)姨拥。如果一個對象只有軟引用绅喉,當(dāng)系統(tǒng)空間足夠時,不會被系統(tǒng)回收叫乌,程序也可以使用該對象柴罐;當(dāng)系統(tǒng)空間不足時,系統(tǒng)將會回收它憨奸。軟引用通常用于對內(nèi)存敏感的程序中革屠。
- `弱引用(WeakReference)`:通過`WeakReference`類實(shí)現(xiàn)。弱引用比軟引用的引用級別更低排宰。如果一個對象只有弱引用似芝,當(dāng)垃圾回收運(yùn)行時,那么無論系統(tǒng)內(nèi)存是否足夠板甘,該對象都會被回收党瓮。
- `虛引用(PhantomReference)`:虛引用完全類似沒有引用。虛引用主要用于跟蹤對象被垃圾回收的狀態(tài)盐类。虛引用不能單獨(dú)使用寞奸,必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用呛谜。
上面三個引用類都包含了一個get()方法,用于獲取被他們所引用的對象蝇闭。
舉一個弱引用的例子:
```
public static void main(String[] strs) {
? ? ? ? String str = new String("哈哈哈");
//? ? ? ? String str = "哈哈哈";
? ? ? ? //創(chuàng)建引用隊(duì)列
? ? ? ? ReferenceQueue rq = new ReferenceQueue();
? ? ? ? //創(chuàng)建一個虛引用
? ? ? ? PhantomReference pr = new PhantomReference(str, rq);
? ? ? ? //創(chuàng)建弱引用對象
//? ? ? ? WeakReference wr = new WeakReference(str);
? ? ? ? str = null;
? ? ? ? System.out.println("去除虛引用所引用的對象:" + pr.get());
//? ? ? ? System.out.println("弱引用被清理前:" + wr.get());
? ? ? ? System.gc();
? ? ? ? System.runFinalization();
//? ? ? ? System.out.println("弱引用被清理后:" + wr.get());
? ? ? ? System.out.println("取出引用隊(duì)列中最先進(jìn)入隊(duì)列的引用與pr比較:" + (rq.poll() == pr));
? ? }
```
被注釋的部分是一個弱引用對象的簡單舉例呻率,未被注釋的部分是虛引用 + 引用隊(duì)列的舉例。
**好處**:
- 使用這些引用類可以避免在程序執(zhí)行期間將對象留在內(nèi)存中呻引,并且垃圾收集器可以隨意的釋放對象礼仗。如果希望盡可能減小程序在其生命周期所占用的內(nèi)存大小時,這些引用類就很有好處逻悠。
> ***注意:要使用這些特殊的引用類元践,就不能保存對對象的強(qiáng)引用。***
當(dāng)程序希望從弱引用中取出引用對象時童谒,該對象可能已經(jīng)被回收了单旁,這時就要重新創(chuàng)建對象。
```
obj = wr.get();
if(obj == null){
//重新創(chuàng)建一個對象饥伊,再次使用虛引用引用它
wr = new WeakReference(recreateIt());//1
//取出虛引用
obj = wr.get();2
}
...操作obj對象...
//再次切斷obj對象強(qiáng)引用
obj = null;
```
這種寫法有一定問題象浑,由于垃圾回收的不確定性,如果系統(tǒng)在1的時候又將弱引用對象回收了琅豆,那么在程序運(yùn)行到2時愉豺,所獲取的對象還是null。正確寫法應(yīng)該是:
```
obj = wr.get();
if(obj == null){
obj = recreatIt();
wr = new WeakReference(obj );
}
...操作obj對象...//這時用強(qiáng)引用直接操作obj對象
//再次切斷obj對象強(qiáng)引用
obj = null;
```
#### 面試題:1. 哪些情況下的對象會被垃圾回收機(jī)制處理掉茫因?
> 答:**不被程序引用的對象**蚪拦。
> **引用計(jì)數(shù)法**(存在缺陷)
> **可達(dá)性分析算法**:虛擬機(jī)會將一些對象定義為GC Roots,從GC Roots出發(fā)一直沿著引用鏈向下尋找冻押,如果某個對象不能通過GC Roots尋找到驰贷,那么虛擬機(jī)就認(rèn)為該對象可以被回收。
![在這里插入圖片描述](https://ask.qcloudimg.com/http-save/yehe-3002827/f9zecp0uiz.jpeg?imageView2/2/w/1620)
滿足以下條件的對象可以看做是GC roots:
? 1. 虛擬機(jī)`棧`中引用的對象洛巢。
? 2. 方法區(qū)中的`靜態(tài)屬性`引用的對象括袒。
? 3. 方法區(qū)中的`常量`引用的對象。
? 4. `本地方法棧`中JNI(Native方法)的引用的對象狼渊。
#### 面試題:2. 垃圾回收機(jī)制何時會進(jìn)行垃圾回收箱熬?
> 答:由于JVM的垃圾回收機(jī)制和不同垃圾回收機(jī)制算法不同,可能是在CPU空閑時狈邑、可能定時發(fā)生城须、也可能是內(nèi)存消耗極限時。
#### 面試題:3.簡述java垃圾回收機(jī)制
>...
#### 面試題:4.java類中成員的初始化順序(包括父類和子類的靜態(tài)代碼塊米苹、靜態(tài)變量糕伐,普通變量和代碼塊以及構(gòu)造方法)
> 答:.用一段程序的運(yùn)行結(jié)果來說明:
> ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190307144527295.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
## 使用Javadoc生成文檔注釋
API文檔主要用于說明類、方法蘸嘶、屬性的功能良瞧,因此javadoc工具只處理文檔源文件在類陪汽、接口、方法褥蚯、屬性挚冤、構(gòu)造器和內(nèi)部類之前的注釋,忽略其他地方的文檔注釋赞庶。并且javadoc只處理`public`和`protected`修飾的類训挡、方法和屬性。如果希望提取privated修飾的內(nèi)容歧强,則可以在使用javadoc工具室添加`-private`選項(xiàng)澜薄。
javadoc常用選項(xiàng):
? - `-d`<directory>: 該選項(xiàng)制定一個路徑,用于將生成的API文檔放到這個路徑下摊册。
? - `-windowtitle`<text>: 該選項(xiàng)指定一個字符串肤京,用于設(shè)置API文檔的瀏覽器`窗口標(biāo)題`。
? - `doctitle`<html-code>: 該選項(xiàng)指定一個HTML的文本茅特,用于指定概述頁面的標(biāo)題忘分。
? - `-header`<html-code>: 該選項(xiàng)指定一個HTML的文本,用于指定概述頁面的頁眉白修。
舉例:
> javadoc -d apidoc -windowtitle 測試 -doctitle 學(xué)習(xí)javadoc工具的測試API文檔 -header 自定義類 Test*.java
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190228163946781.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
## Java關(guān)鍵字
| abstract | assert | boolean | break | byte | case |
--|--|--|--|--|--
| catch | char | class| continue | default | do |
| double | else | enum | extends| final | finally |
| float | for | if | implements | import | int |
| interface | instanceof | long | native | new | package|
| private | protected | public | return | short | static|
| strictfp | super | switch | synchronized | this | throw |
| throws | transient | try | void | volatile | while |
除了上面48個關(guān)鍵字饭庞,java還包含兩個保留字:`goto`和`const`
Java還提供了3個特殊的直接量(literal):`true`、`false`和`null`
## Java數(shù)據(jù)類型分類
Java支持的類型氛圍兩類:`基本類型`和`引用類型`熬荆。
基本類型包括`boolean類型`和`數(shù)值類型`。
數(shù)值類型有`整數(shù)類型`和`浮點(diǎn)類型`绸狐。
整數(shù)型包括byte卤恳、short、int寒矿、long突琳、char,浮點(diǎn)類型包括float符相、和double拆融。
> ***注意:有的時候也把char型稱為字符型,實(shí)際上字符型也是一種整數(shù)型啊终。***
> ***注意:空引用(null)只能被轉(zhuǎn)換成引用類型镜豹,不能被轉(zhuǎn)換成基本類型。***
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190228172437905.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
### 整型:
- `byte`:一個byte型整數(shù)在內(nèi)存里占8位蓝牲,表數(shù)范圍是-128~127(2的7次方)趟脂。
- `short`: 一個short型整數(shù)在內(nèi)存里占16位,表數(shù)范圍是-32768~32767(2的15次方).
- `int`: 一個int型整數(shù)在內(nèi)存里占32位例衍,表數(shù)范圍是-2147483648到2147483647(2的31次方)
- `long`: 一個long型整數(shù)在內(nèi)存里占64位昔期,表數(shù)范圍是-9223372036854775808~9223372036854775807已卸。(2的63次方)
Java中整數(shù)常量有3種表示方式:10進(jìn)制、8進(jìn)制和16進(jìn)制硼一。
8進(jìn)制整數(shù)常量以0開頭累澡。16進(jìn)制的整數(shù)以0x或0X開頭。
例如:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190228174033181.png)
### 字符型
Java語言使用`Unicode編碼集`作為編碼方式般贼,Unicode支持世界上所有書面語言字符愧哟,因此Java支持各種語言字符。
字符常量有三種表現(xiàn)方式:
? - 直接通過`單個字符`來指定字符常量具伍,例如翅雏,‘A’,‘9’人芽,‘0’等望几。
? - 通過`轉(zhuǎn)義字符`表示特殊字符常量,例如萤厅,‘\n’橄抹,‘\t’等。
? - 直接用`Unicode值`來表示字符常量惕味,格式是'\uXXXX'楼誓,其中XXXX表示一個16進(jìn)制的整數(shù)。
| 轉(zhuǎn)義字符 |說明? | Unicode表示方式 |
|--|--|--|--|
| \b | 退格符 | \u0008 |
| \n | 換行符 | \u000a |
| \r | 回車符 | \u000d |
| \t | 制表符 | \u0009 |
| \" | 雙引號 | \u0022 |
| \' | 單引號 | \u0027 |
| \\ | 反斜杠 | \u005c |
char類型的值也可以直接作為`整數(shù)型`的數(shù)值來使用名挥,但它是一個16位無符號整數(shù)疟羹,即全部是正數(shù),表數(shù)范圍是0~65535禀倔。
### 浮點(diǎn)型:
Java浮點(diǎn)類型有兩種:`float`和`double`榄融。
- `float`: 單精度浮點(diǎn)數(shù),占4個字節(jié)救湖,32位愧杯。第一位是符號位,接下來8位表示指數(shù)鞋既,接下來23位表示尾數(shù)力九。
- `double`: 雙精度浮點(diǎn)數(shù),占8個字節(jié)邑闺,64位跌前。第一位是符號位,接下來11位表指數(shù)检吆,接下來52位表尾數(shù)舒萎。
Java浮點(diǎn)數(shù)有兩種表現(xiàn)形式:
? - 1. 十進(jìn)制數(shù)形式。
? - 2. 科學(xué)計(jì)數(shù)法形式。
> ***注意:Java浮點(diǎn)數(shù)使用二進(jìn)制的科學(xué)計(jì)數(shù)法來表示臂寝,因此可能不精確標(biāo)識一個浮點(diǎn)數(shù)章鲤。雖然double比float更精準(zhǔn),但是還是可能出現(xiàn)這種情況咆贬。如果要精確保存一個浮點(diǎn)數(shù)败徊,可以考慮使用`BigDecimal`類。[精確浮點(diǎn)運(yùn)算傳送門](https://blog.csdn.net/weixin_39397471/article/details/88050491)***
只有`浮點(diǎn)類型`的數(shù)值才能用科學(xué)計(jì)數(shù)法表示掏缎。例如51200是一個int類型的值皱蹦,512E2則是一個浮點(diǎn)型的值。
Java還提供了三個特殊的浮點(diǎn)數(shù)值:`正無窮大`眷蜈、`負(fù)無窮大`和`非數(shù)`沪哺,用于表示溢出和出錯。
- `正無窮大`:正數(shù)除以0得到正無窮大酌儒」技耍可以通過Double或Float的POSITIVE表示。
- `負(fù)無窮大`:負(fù)數(shù)除以0的到負(fù)無窮大忌怎〖危可以通過Double或Float的NEGATIVE_INFINITY表示。
- `非數(shù)`:0.0除以0.0或?qū)ω?fù)數(shù)開方得到一個非數(shù)榴啸。非數(shù)通過Double或Float的NaN表示孽惰。
所有正無窮大數(shù)值都是相等的,所有負(fù)無窮大數(shù)值也是相等的鸥印,而NaN不與任何數(shù)值相等勋功,甚至不和NaN相等。
> ***注意:只有`浮點(diǎn)數(shù)`除以0才可以得到正無窮大或負(fù)無窮大库说。因?yàn)镴ava會自動把和浮點(diǎn)數(shù)運(yùn)算的0當(dāng)成0.0處理酝润。如果一個整數(shù)除以0,則會拋異常璃弄。***
#### 面試題:1.int、char构回、long各占多少字節(jié)數(shù)
> 答:int占4個字節(jié)夏块,char占2個字節(jié),long占8個字節(jié)纤掸。
#### 面試題:2.Math.round(-11.5)與Math.round(11.5)的值各是多少脐供?
> 答:-11和12
> 1、小數(shù)點(diǎn)后第一位=5
2借跪、正數(shù):Math.round(11.5)=12
3政己、負(fù)數(shù):Math.round(-11.5)=-11
4、
5掏愁、小數(shù)點(diǎn)后第一位<5
6歇由、正數(shù):Math.round(11.46)=11
7卵牍、負(fù)數(shù):Math.round(-11.46)=-11
8、
9沦泌、小數(shù)點(diǎn)后第一位>5
10糊昙、正數(shù):Math.round(11.68)=12
11、負(fù)數(shù):Math.round(-11.68)=-12
> </br>
> 總結(jié)規(guī)律:
>? ? 1. 小數(shù)點(diǎn)后第一位小于5:直接舍去小數(shù)部分谢谦。
>? ? 2. 小數(shù)點(diǎn)后第一位等于5:正數(shù)直接加1释牺,負(fù)數(shù)舍去小數(shù)部分。
>? ? 3. 小數(shù)點(diǎn)后第一位大于5:整數(shù)部分絕對值加1回挽,正負(fù)不變没咙。
### 位運(yùn)算符:
Java支持的運(yùn)算符有:
? - `&`: 按位與。
? - `|`:按位或千劈。
? - `~`: 按位非祭刚。
? - `^`: 按位異或。
? - `<<`:左位移運(yùn)算符队塘。
? - `>>`:右位移運(yùn)算符袁梗。
? - `>>>`:無符號右移運(yùn)算符。
| 第一個運(yùn)算數(shù) | 第二個運(yùn)算數(shù) | 按位與 | 按位或 | 按位異或 |
|--|--|--|--|--|
| 0 | 0 | 0 | 0 | 0? |
| 1 | 1 | 1 | 1 |? 1 |
| 1 | 0 | 0 | 1 |? 1 |
| 0 | 1 | 0 | 1 | 0? |
`~`運(yùn)算符運(yùn)算規(guī)則:
? 1. 首先原碼除符號位外取反得到反碼憔古。
? 2. 反碼加1得到補(bǔ)碼遮怜。
? 3. 再取反得到結(jié)果。(此時符號位也取反)
例如:~-5 = 4
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190301113429273.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
補(bǔ)充一下十進(jìn)制負(fù)數(shù)轉(zhuǎn)二進(jìn)制的知識點(diǎn):
> 先說一下原碼鸿市、反碼與補(bǔ)碼锯梁。
1. `原碼`:符號位加上數(shù)字的二進(jìn)制表示,int為例焰情,第一位表示`符號 `(0正數(shù) 1負(fù)數(shù))陌凳,對于原碼來說,絕對值相等的正數(shù)和負(fù)數(shù)只有符號位不同内舟。
2. `反碼`:如果一個數(shù)為正合敦,則與補(bǔ)碼相同。如果一個數(shù)為負(fù)验游,則符號位為1(`符號位不變化充岛,其余位數(shù)取反`)
3. `補(bǔ)碼`:如果一個數(shù)如果為正,則它的原碼耕蝉、反碼崔梗、補(bǔ)碼相同;一個數(shù)如果為負(fù)垒在,去到反碼然后加1(`反碼加1就是補(bǔ)碼`)蒜魄。Java使用補(bǔ)碼表示負(fù)數(shù)。
負(fù)數(shù)轉(zhuǎn)二進(jìn)制步驟:-3
1. 首先將負(fù)數(shù)轉(zhuǎn)換為對應(yīng)的原碼。
`0000 0000 0000 0000 0000 0000 0000 0011`
2. 再將原碼按位取反谈为,得到反碼旅挤。
`1111 1111 1111 1111 1111 1111 1111 1100 `
3. 將反碼+1得到補(bǔ)碼。
`1111 1111 1111 1111 1111 1111 1111 1101 `
這就是負(fù)數(shù)的二進(jìn)制表示了峦阁。
逆轉(zhuǎn)這個過程得到十進(jìn)制的數(shù)谦铃。1111 1111 1111 1111 1111 1111 1111 1101
1. 先取反,得到反碼:
`0000 0000 0000 0000 0000 0000 0000 0010`
2. 反碼+1,得到:
`0000 0000 0000 0000 0000 0000 0000 0011`
3. 轉(zhuǎn)為10進(jìn)制榔昔,最后的到3驹闰。
> ***注意:如果int數(shù)值類型位數(shù)不滿32位,需要在高位補(bǔ)0撒会。***
Java的右移運(yùn)算符有兩個嘹朗,>>和>>>
1. `>>`:把操作時的二進(jìn)制碼右移指定位數(shù)后,左邊空出來的位數(shù)以`符號位`補(bǔ)充诵肛。
2. `>>>`:把操作時的二進(jìn)制碼右移指定位數(shù)后屹培,左邊空出來的位數(shù)以`0`補(bǔ)充。
`>>`怔檩、`>>>`和`<<`三個位移運(yùn)算只適合對byte褪秀、short、char薛训、int和long等整型進(jìn)行運(yùn)算媒吗,同時還有以下運(yùn)算規(guī)則:
? - 對于低于int(byte、short等)總是先自動類型轉(zhuǎn)換位int后再位移乙埃。
? - 對于int類型的整數(shù)`a>>b`闸英,系統(tǒng)先用32對b取余后再進(jìn)行運(yùn)算,例如:a>>33和a>>1結(jié)果相同介袜,a>>32和a結(jié)果一樣甫何。
? - 對于long類型,則是用64對b進(jìn)行取余遇伞,因?yàn)閘ong類型是64位的辙喂。
### 比較運(yùn)算
數(shù)值型對應(yīng)的包裝類的實(shí)例是可以與數(shù)值型的值進(jìn)行比較的,這種比較是直接取出包裝類所包裝的`數(shù)值`進(jìn)行比較鸠珠,也就是自動`拆箱`比較加派。
在看下面這段代碼:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190301140152668.png)
同樣的兩個Integer實(shí)例,裝箱后結(jié)果為什么不一樣呢跳芳?
這跟Integer的設(shè)計(jì)有關(guān):
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190301140345581.png)
從上面的代碼可以看出,系統(tǒng)把一個`-128~127`之間的數(shù)字自動裝箱成Integer竹勉,并放入了一個名為cache的數(shù)組保存起來飞盆。當(dāng)有這個范圍的數(shù)值需要裝箱時,直接引用到cache數(shù)組中對應(yīng)的值,所以在這個范圍內(nèi)的數(shù)組裝箱后`全部相等`吓歇。
與此類似的還有String類孽水,String類也會對通過直接量直接賦值的String實(shí)例進(jìn)行緩存。如圖:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190301141317139.png)
### 循環(huán)
使用`break`結(jié)束一個循環(huán):break用于完全結(jié)束一個循環(huán)城看,跳出循環(huán)體女气。
`break`不僅可以結(jié)束其所在的循環(huán)险耀,還可以結(jié)束其外層循環(huán):
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190301143750885.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
break后緊跟一個標(biāo)簽語句吼驶,會讓程序直接結(jié)束outer指定的循環(huán)。
> ***注意:break后必須是一個有效標(biāo)簽券躁,且必須再break所在循環(huán)的外層循環(huán)之前定義才有意義轰胁。***
`continue·`可以用于終止本次循環(huán)谒主。
與break類似,`continue`也可以緊跟一個標(biāo)簽赃阀,用于直接結(jié)束標(biāo)簽所標(biāo)識循環(huán)的當(dāng)次循環(huán)霎肯,重新開始下一次循環(huán)。
用法與注意與break一致榛斯。
### 數(shù)組
定義數(shù)組語法:
? - type[] arrayName?
? - type arrayName[];(不推薦)
type[]是一種新類型观游,與type類型完全不同。例如int是基本類型驮俗,int[]是引用類型懂缕。
> ***注意:定義數(shù)組時不能指定數(shù)組長度(動態(tài)初始化時可以指定長度)。***
> ***注意:foreach循環(huán)迭代數(shù)組元素時意述,并不能改變數(shù)組元素的值提佣,因此不要對foreach的循環(huán)變量進(jìn)行賦值。***
實(shí)際`數(shù)組元素`被存儲在`堆`(heap)內(nèi)存中荤崇;數(shù)組引用變量是一個`引用類型變量`拌屏,被存儲在`棧`(stack)內(nèi)存中。
## 面向?qū)ο?/p>
static修飾的成員不能訪問沒有static修飾的成員术荤。
靜態(tài)成員不能直接訪問非靜態(tài)成員倚喂。
static修飾的方法無論是`類本身`或是`對象`調(diào)用都會得到相同的執(zhí)行結(jié)果。
### 方法的參數(shù)傳遞機(jī)制
一段代碼執(zhí)行的結(jié)果就足以說明問題了:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190306154004915.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
- 基本類型參數(shù)傳遞的是值瓣戚,即`值傳遞`端圈。就是將實(shí)際參數(shù)值得副本(復(fù)制品)傳入方法內(nèi),而參數(shù)本身不會受到任何影響子库。
- 引用類型參數(shù)傳遞的是地址舱权,即`址傳遞`。
其實(shí)參數(shù)傳遞的也是值仑嗅,從底層來看宴倍,引用對象是將引用對象拷貝了一份傳到方法中张症,此時堆內(nèi)存存放的真正對象有兩個引用變量,用圖說明:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190306155954912.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
這兩個引用變量確實(shí)是兩個鸵贬,但是引用的對象本身只有堆內(nèi)存的唯一一個俗他。所以現(xiàn)在無論哪個引用變量為對象賦值,改變的都是同一個對象阔逼。
更直觀的證明一下兆衅,可以在調(diào)用完swap方法后,將dw對象引用指向null嗜浮,就變?yōu)椋?/p>
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190306160223669.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
此時swap中的引用斷了羡亩,但main方法棧中引用不受影響,這確實(shí)是兩個引用對象周伦。當(dāng)main方法棧中的引用也斷了時夕春,堆內(nèi)存中的對象將沒有引用,就會變?yōu)橐粋€垃圾對象专挪,垃圾回收機(jī)制將在適當(dāng)時機(jī)來回收及志。
### 形參長度可變的方法
JDK1.5之后,Java允許定義形參長度可變的方法寨腔,定義方式與規(guī)則如下:
? - 長度可變的形參只能處于形參列表的最后速侈。
? - 一個方法中只能包括一個長度可變的形參。
? - 調(diào)用包含一個長度可變的形參方法時迫卢,這個長度可變的形參即可以傳入多個參數(shù)倚搬,也可以傳入一個數(shù)組。
```
//長度可變形參
? ? public static void sayList(String... strs) {
? ? ? ? System.out.println("傳入?yún)?shù)是:");
? ? ? ? for (int i = 0; i < strs.length; i++) {
? ? ? ? ? ? System.out.println(strs[i]);
? ? ? ? }
? ? }
```
```
//調(diào)用:
sayList("李森","大錘","大寶");//使用多個參數(shù) 調(diào)用長度可變形參
sayList(new String[]{"李森","大錘","大寶"});//使用數(shù)組 調(diào)用長度可變形參
```
運(yùn)行結(jié)果是一樣的:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/2019030616184821.png)
### 成員變量的初始化和內(nèi)存中的運(yùn)行機(jī)制
一個類在使用之前要經(jīng)過類加載乾蛤、類驗(yàn)證每界、類準(zhǔn)備、類解析類初始化等幾個階段家卖。
以Person類為例眨层,系統(tǒng)會在第一次使用Person類時加載這個類,并初始化這個類上荡。
在類的準(zhǔn)備階段趴樱,系統(tǒng)將會為該類的`類屬性`分配內(nèi)存空間,并指定默認(rèn)初始值酪捡。如圖:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190307104556689.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
在系統(tǒng)創(chuàng)建一個Person對象時叁征,實(shí)例屬性是在創(chuàng)建實(shí)例時分配內(nèi)存空間、并指定初始值的逛薇。
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190307104817195.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTM5NzQ3MQ==,size_16,color_FFFFFF,t_70)
### 局部變量的初始化和內(nèi)存中的運(yùn)行機(jī)制
局部變量定義后捺疼,必須經(jīng)過`顯示初始化`后才能使用,系統(tǒng)不會為局部變量執(zhí)行初始化永罚。直到程序?yàn)檫@個變量賦值時啤呼,系統(tǒng)才會為局部變量分配內(nèi)存议薪。
與成員變量不同,局部變量不屬于任何類或?qū)嵗庇眩虼怂偸潜4嬖谄渌诜椒ǖ腵棧內(nèi)存`中。
- 如果局部變量是`基本類型`變量产捞,則直接把這個變量的值保存在該變量對應(yīng)的內(nèi)存中醇锚;
- 如果局部變量是`引用類型`變量,則這個變量里存放的是地址坯临,通過該地址引用到該變量實(shí)際引用的對象或數(shù)組焊唬。
### 使用訪問控制符
Java的訪問控制級別由小到大依次如圖:
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190307111000163.png)
- `private`:類訪問權(quán)限。只能在該類的內(nèi)部訪問看靠。
- `default`:包訪問權(quán)限赶促。可以被相同包下其他類訪問挟炬。
- `protected`:子類訪問權(quán)限鸥滨。即可以被同一包其他類訪問,也可以被不同包下子類訪問谤祖。
- `public`:公共訪問權(quán)限婿滓。可以被所有類訪問粥喜。
|? | private | default | protected | public |
|--|--|--|--|--|
| 同一類中 | √ | √ | √ | √ |
| 同一包中 |? | √ | √ | √ |
| 子類中 |? |? | √ | √ |
| 全局范圍內(nèi) |? |? |? | √ |
> ***注意:如果一個Java源文件里的所有類都沒有使用public修飾凸主,則這個Java源文件的文件名可以是一切合法文件名;但如果一個Java源文件里定義了一個public修飾的類额湘,則這個源文件的文件名必須與public類的類名相同卿吐。***
### package和import
package語句必須作為源文件第一句非注釋語句。
一個源文件只能有一個包(只包含一條package語句)锋华。
Java包機(jī)制需要兩個方面的保證:
1. 源文件里使用package語句指定包名嗡官。
2. class文件必須放在對應(yīng)的路徑下。
- `import`語句:`*`可以表示包下所有類供置,而不能表示包谨湘。
例如:import package.subpackage.*;表示引入subpackage下所有類。
- `import static`語句:是JDK1.5引入的一種靜態(tài)導(dǎo)入的語法芥丧,用于導(dǎo)入指定類的某個靜態(tài)屬性或全部靜態(tài)屬性值紧阔。`*`表示類下全部屬性名。
例如:import staticpackage.subpackage.ClassName.*;
### Java的常用包
- `java.lang`:包含Java語言核心類续担,如String擅耽、Math、System和Thread等物遇,系統(tǒng)會自動導(dǎo)入這個包下所有類乖仇。
- `java.util`:包含Java大量工具類/接口和集合框架/接口憾儒,如Arrays、List和Set等乃沙。
- `java.net`:包含Java網(wǎng)絡(luò)編程相關(guān)類/接口起趾。
- `java.io`:包含Java輸入/輸出編程相關(guān)的類/接口。
- `java.text`:包含一些Java格式化相關(guān)的類警儒。
- `java.sql`:包含Java進(jìn)行DJBC數(shù)據(jù)庫編程的相關(guān)類/接口训裆。
- `java.awt`:包含抽象窗口工具集(Abstract Window ToolKits)的相關(guān)類/接口,這些類主要用于構(gòu)建圖形用戶界面(GUI)程序蜀铲。
- `java.swing`:包含Swing圖形用戶界面編程的相關(guān)類/接口边琉,這些類可用于構(gòu)建平臺無關(guān)的GUI程序。
### 重寫父類的方法
方法的重寫要遵循“**兩同兩小一大**”记劝,
- `“兩同”`:方法名相同变姨,形參列表相同。
- `“兩小”`:子類方法返回值應(yīng)比父類方法返回值類型更小或相等厌丑。子類方法聲明拋出的異常應(yīng)比父類的方發(fā)聲明拋出的異常類更小或相等定欧。
-` “一大”`:子類方法的訪問權(quán)限應(yīng)比父類方法更大或相等。
> ***注意:覆蓋方法和被覆蓋的方法要么都是類方法蹄衷,要么都是實(shí)例方法忧额,不能一個是類方法,一個是實(shí)例方法愧口。***
#### 面試題 1.父類的靜態(tài)方法能否被子類重寫
> 答:可以睦番,子類可以重寫父類靜態(tài)方法。
### 利用組合實(shí)現(xiàn)復(fù)用
直接用一段代碼來說明:
```
class Animal {
? ? private void beat() {
? ? ? ? System.out.println("心臟跳動耍属。托嚣。。");
? ? }
? ? public void breach() {
? ? ? ? beat();
? ? ? ? System.out.println("吸一口氣厚骗,吐一口氣示启,呼吸中。领舰。夫嗓。");
? ? }
}
class Wolf {
? ? //將要組合部分嵌入類中屬性,實(shí)現(xiàn)組合(有點(diǎn)類似于代理模式)
? ? private Animal animal;
? ? public Wolf(Animal animal) {
? ? ? ? this.animal = animal;
? ? }
? ? public void run() {
? ? ? ? //直接復(fù)用Animal提供的breath方法
? ? ? ? animal.breach();
? ? ? ? System.out.println("在陸地快速奔跑冲秽。舍咖。。");
? ? }
}
public class ZuHeDemo {
? ? public static void main(String[] strs) {
? ? ? ? Animal animal = new Animal();
? ? ? ? Wolf wolf = new Wolf(animal);
? ? ? ? wolf.run();
? ? }
}
```
### 接口與抽象類
接口與抽象類特征:
- 都不能被實(shí)例化锉桑,它們都位于繼承樹的頂端排霉,用于被其他類實(shí)現(xiàn)和繼承。
- 接口和抽象類都可以包含抽象方法民轴,實(shí)現(xiàn)接口或繼承抽象類的普通子類都必須實(shí)現(xiàn)這些抽象方法攻柠。
接口與抽象類用法差別:
- 接口里只能包含抽象方法球订;抽象類則完全可以包含普通方法。
- 接口里不能定義靜態(tài)方法瑰钮;抽象類里可以定義靜態(tài)方法冒滩。
- 接口里只能定義靜態(tài)常量屬性,不能定義普通屬性浪谴;抽象類里則既可以定義靜態(tài)常量屬性旦部,也可以定義普通屬性。
- 接口不包含構(gòu)造器较店;抽象類可以包含構(gòu)造器,抽象類里的構(gòu)造器并不是用于創(chuàng)建對象容燕,而是讓其子類調(diào)用這些構(gòu)造器來完成屬于抽象類的初始化操作梁呈。
- 接口里不能包含初始化塊,抽象類則可以包含初始化塊蘸秘。
- 一個類最多只能有一個直接父類官卡,包括抽象類。但一個類可以實(shí)現(xiàn)多個接口醋虏。
#### 面試題 1.接口與抽象類的區(qū)別
> 答:接口與抽象類的差別非常大寻咒,這種差別主要體現(xiàn)在二者的設(shè)計(jì)目的上【苯溃總的來說接口是對動作的抽象毛秘,抽象類是對根源的抽象。
> 接口體現(xiàn)的是一種規(guī)范阻课。在程序中使用接口時叫挟,接口是多個模塊間的耦合標(biāo)準(zhǔn)。接口是一個契約限煞,定義接口一定要慎重抹恳,因?yàn)橐坏┙涌谛薷模瑢φ麄€系統(tǒng)甚至其他系統(tǒng)的影響將是輻射式的署驻,導(dǎo)致系統(tǒng)中大部分類都需要改寫奋献。
> 抽象類體現(xiàn)的是一種模板式的設(shè)計(jì)。
### 內(nèi)部類
成員內(nèi)部類是一種與屬性旺上、方法構(gòu)造器和初始化相似的類成員瓶蚂,局部內(nèi)部類和匿名內(nèi)部類則不是類成員。
非靜態(tài)內(nèi)部類中不能有靜態(tài)方法抚官、靜態(tài)屬性扬跋、靜態(tài)初始化塊。
非靜態(tài)內(nèi)部類默認(rèn)持有外部類的引用凌节,這也是容易造成內(nèi)存泄漏的一個危險(xiǎn)點(diǎn)钦听。
> ***注意:靜態(tài)內(nèi)部類里不可以有靜態(tài)初始化代碼塊洒试,但可以包含普通初始化塊。***
#### 面試題 1.什么是內(nèi)部類 朴上,內(nèi)部類作用
> 答:把一個類放到另一個類的內(nèi)部定義垒棋,這個定義在其他類內(nèi)部的類就被稱為內(nèi)部類。
> 內(nèi)部類作用:
> 1. 內(nèi)部類提供了更好的封裝痪宰,可以把內(nèi)部類隱藏在外部類之內(nèi)叼架。
> 2. 內(nèi)部類成員可以直接訪問外部類的私有數(shù)據(jù),因?yàn)閮?nèi)部類被當(dāng)做其外部類成員衣撬,同一個類的成員可以相互訪問乖订。但外部類不可以訪問內(nèi)部類細(xì)節(jié)。
> 3. 匿名內(nèi)部類適合用于創(chuàng)建那些僅需要一次使用的類具练。
### 靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類可以包含靜態(tài)成員乍构,可以包含非靜態(tài)成員。
靜態(tài)內(nèi)部類也可以定義在接口里扛点。
#### 匿名內(nèi)部類
匿名內(nèi)部類應(yīng)該遵循兩條規(guī)則:
- 匿名內(nèi)部類不能是抽象類
- 匿名內(nèi)部類不能定義構(gòu)造器
#### 閉包(Closure)和回調(diào)
代碼是最好的實(shí)踐哥遮,直接通過代碼說明:
```
//程序員
class Programmer{
? ? private String name;
? ? public Programmer(String name) {
? ? ? ? this.name = name;
? ? }
? ? public void work(){
? ? ? ? System.out.println(name + "正在敲代碼...");
? ? }
}
//教師
interface Teacher{
? ? void work();
}
//既是程序員也是教師
class TeachProgrammer extends Programmer{
? ? public TeachProgrammer(String name) {
? ? ? ? super(name);
? ? }
? ? public void teach(){
? ? ? ? System.out.println("教師正在臺上講課...");
? ? }
? ? private class Closure implements Teacher{
? ? ? ? @Override
? ? ? ? public void work() {
? ? ? ? ? ? teach();
? ? ? ? }
? ? }
? ? public Teacher getCallBack(){
? ? ? ? return new Closure();
? ? }
}
public class ClosureCallBackDemo {
? ? public static void main(String[] strs) {
? ? ? ? TeachProgrammer tp = new TeachProgrammer("白澤");
? ? ? ? //直接調(diào)用從程序員繼承的工作方法(work)
? ? ? ? tp.work();
? ? ? ? //表面上調(diào)用Teacher的work(),實(shí)際上回調(diào)的是teach()方法
? ? ? ? tp.getCallBack().work();
? ? }
}
```
內(nèi)部類可以很方便的調(diào)用其外部類的屬性方法陵究,這樣可以讓編程更加靈活眠饮。
### 枚舉類
枚舉類與普通類區(qū)別:
- 枚舉類可以實(shí)現(xiàn)一個或多個接口,使用enum關(guān)鍵字定義的枚舉類默認(rèn)繼承了`java.lang.Enum`類铜邮,而不是`Object`仪召。其中Enum實(shí)現(xiàn)了`java.lang.Serializable`和`java.lang.Comparable`兩個接口。
- 枚舉類的構(gòu)造器只能使用`private`修飾松蒜。
- 枚舉類的所有實(shí)例必須在枚舉類中`顯示列出`返咱。列出這些實(shí)例時,系統(tǒng)會默認(rèn)添加`public static final`修飾符牍鞠。
- 所有枚舉類都提供了一個`values`方法咖摹,可以遍歷所有枚舉值。
舉一個支付狀態(tài)的枚舉類:
```
interface PayStateInterface {
? ? void info();
}
public enum PayState implements PayStateInterface {//支付狀態(tài)(0未支付 10 已支付)
? ? WAIT_PAY(0) {
? ? ? ? public void info() {
? ? ? ? ? ? System.out.println("這個狀態(tài)是待支付狀態(tài)");
? ? ? ? }
? ? }, ALREAD_PAY(10) {
? ? ? ? public void info() {
? ? ? ? ? ? System.out.println("這個狀態(tài)是已支付");
? ? ? ? }
? ? };
? ? private final int value;
? ? private PayState(int value) {
? ? ? ? this.value = value;
? ? }
? ? public static PayState valueOf(int type) {
? ? ? ? switch (type) {
? ? ? ? ? ? case 0:
? ? ? ? ? ? ? ? return WAIT_PAY;
? ? ? ? ? ? case 10:
? ? ? ? ? ? ? ? return ALREAD_PAY;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? return null;
? ? ? ? }
? ? }
? ? public int getValue() {
? ? ? ? return value;
? ? }
}
```
舉例代碼中還用到了枚舉類實(shí)現(xiàn)接口知識點(diǎn)难述,可以根據(jù)不同實(shí)例來實(shí)現(xiàn)各自方法萤晴,也可以由枚舉類實(shí)現(xiàn)一個公共的方法。
java.lang.Enum類中提供了一些方法:
- `int compareTo(E o)`:用于與指定枚舉對象比較順序胁后,如果該枚舉對象位于指定枚舉對象之后店读,返回正整數(shù),位于指定枚舉對象之前攀芯,返回負(fù)整數(shù)屯断,否則返回0。
- `int ordinal()`;返回枚舉值在枚舉類中的索引值。(第一個枚舉值的索引值為0)
- `public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name)`:用于返回指定枚舉類中指定名稱的枚舉值殖演。
- `String toString()`:返回枚舉常量的名稱氧秘。
- `String name()`:與toString()類似。
### Java修飾符適用范圍總表
|? | 頂層類/接口 | 成員屬性 | 方法 | 構(gòu)造器 | 初始化塊 | 成員內(nèi)部類 | 局部成員 |
|--|--|--|--|--|--|--|--|
| public | √ | √ | √ | √ |? | √ |? |
| protected |? | √ | √ | √ |? | √ |? |
| 包訪問控制符 | √ | √ | √ | √ | O | √ | O |
| private |? | √ | √ | √ |? | √ |? |
| abstract | √ |? | √ |? |? | √ |? |
| final | √ | √ | √ |? |? | √ | √ |
| static |? | √ | √ |? |? | √ |? |
| strictfp | √ |? | √ |? |? | √ |? |
| synchronized |? |? | √ |? |? |? |? |
| native |? |? | √ |? |? |? |? |
| transient |? | √ |? |? |? |? |? |
| volatile |? | √ |? |? |? |? |? |
- `strictfp`關(guān)鍵字含義是FP-strict趴久,就是`精確浮點(diǎn)`的意思丸相。如果想讓浮點(diǎn)運(yùn)算更加精準(zhǔn),就可以使用strictfp修飾類彼棍、接口和方法灭忠。修飾的范圍內(nèi)Java編譯器和運(yùn)行環(huán)境會完全依照浮點(diǎn)規(guī)范IEEE-754來執(zhí)行。
- `native`:使用native修飾的方法類似于一個抽象方法座硕。如果某個方法需要利用`平臺相關(guān)特性`弛作,或者訪問系統(tǒng)硬件時,則可以把該方法使用native修飾华匾,再把該方法交給`C`去實(shí)現(xiàn)缆蝉。一旦Java程序中包含native方法,這個程序?qū)⑹タ缙脚_的功能瘦真。
## 問答模塊
### 1. JRE和JVM的關(guān)系是怎樣的?
> 答:簡單地說:**JRE包含JVM**黍瞧。
> JVM是運(yùn)行Java程序的核心虛擬機(jī)诸尽,而運(yùn)行Java程序不僅需要核心虛擬機(jī),還需要其他的類加載器印颤,字節(jié)碼校驗(yàn)器以及大量的基礎(chǔ)類庫您机。JRE出了包含JVM之外,還包含運(yùn)行Java程序的其他環(huán)境支持年局。
> ***注意:所有Java關(guān)鍵字都是小寫的际看,true、false和null都不是Java關(guān)鍵字矢否。***
### 2.為什么有棧內(nèi)存和堆內(nèi)存之分仲闽?
> 答:當(dāng)一個方法執(zhí)行時,每個`方法`都會建立自己的`內(nèi)存棧`僵朗,在這個方法內(nèi)定義的`變量`會逐個放在這塊內(nèi)存棧里赖欣,隨著方法的執(zhí)行結(jié)束,這個方法的內(nèi)存棧也將自然銷毀了验庙。因此顶吮,所有**在方法中定義的變量都是放在棧內(nèi)存中的**;當(dāng)我們在程序中創(chuàng)建一個對象時粪薛,這個對象將被保存到`運(yùn)行時數(shù)據(jù)區(qū)`中悴了,以便反復(fù)利用(因?yàn)閷ο髣?chuàng)建的成本通常較大),這個運(yùn)行時數(shù)據(jù)區(qū)就是`堆內(nèi)存`。堆內(nèi)存中的對象**不會隨方法的結(jié)束而銷毀**湃交,即使方法結(jié)束后熟空,這個對象還可能被另一個引用變量所引用(方法的參數(shù)傳遞時很常見),則這個對象依然不會銷毀巡揍。只有一個對象沒有任何引用變量引用它時痛阻,系統(tǒng)的垃圾回收機(jī)制才會在合適的時候回收它。
### 3.為什么方法的返回值類型不能用于區(qū)分重載的方法
> 答:對于int f()和String f()兩個方法腮敌,如果這樣調(diào)用:int result = f();阱当,系統(tǒng)可以識別我們是想用返回值類型為int的方法;但java調(diào)用方法時可以忽略返回值糜工,如果這樣調(diào)用:f();弊添,可以判斷調(diào)用哪個方法嗎?Java系統(tǒng)也會糊涂捌木。系統(tǒng)一糊涂油坝,肯定就是你錯了。因此刨裆,**java里不能使用返回值類型作為區(qū)分方法重載的依據(jù)**澈圈。
### 4.非靜態(tài)內(nèi)部類對象和外部類對象的關(guān)系是怎樣的?
> 答:非靜態(tài)內(nèi)部類對象必須寄存在外部類對象里帆啃,而外部類對象則非必須有非靜態(tài)內(nèi)部類對象寄存在其中瞬女。因此外部類訪問訪問費(fèi)靜態(tài)內(nèi)部類成員時,可能非靜態(tài)內(nèi)部類對象根本不存在努潘,為非靜態(tài)內(nèi)部類訪問外部類成員時诽偷,外部類對象一定存在。