此文已經(jīng)同步至個(gè)人站點(diǎn)博客坦冠,點(diǎn)擊下方鏈接可以體驗(yàn)更加閱讀模式:
《java題庫》
final,finalize,finally關(guān)鍵字
1.finalize和final關(guān)鍵字
什么是finalize()方法形耗?finalize()方法什么時(shí)候被調(diào)用?
答: Java允許在類中定義一個(gè)名為finalize()
的方法辙浑,一旦垃圾回收器準(zhǔn)備好釋放對(duì)象占用的存儲(chǔ)空間激涤,將首先調(diào)用finalize()
方法,并且在下一次垃圾回收動(dòng)作發(fā)生時(shí)判呕,才會(huì)真正回收對(duì)象占用的內(nèi)存倦踢。
析構(gòu)函數(shù)(finalization)的目的是什么
析構(gòu)函數(shù)目的是撤銷對(duì)象前送滞、完成一些清理工作,比如釋放資源辱挥。釋放了之后這些資源可以被回收犁嗅,重新利用。
final關(guān)鍵字有哪些用法
final關(guān)鍵字主要用于修飾類晤碘、類成員褂微、方法、以及方法的形參园爷。
- final修飾成員屬性:說明該成員屬性是常量宠蚂,不能被修改;
- final修飾類童社,該類是最終類求厕,不能被繼承。
- final修飾方法:該方法是最終方法叠洗,不能被重寫甘改。
- final關(guān)鍵字修飾形參:1:當(dāng)形參被修飾為final,那么該形參所屬的方法中不能被篡改。
2. final 與 static 關(guān)鍵字可以用于哪里灭抑?它們的作用是什么十艾?
用于修飾成員變量和成員方法,可以理解為“全局常量”腾节,對(duì)于變量表示一旦給定值就不可以修改忘嫉,并且通過類名可以訪問;對(duì)于方法表示不可覆蓋案腺,并且可以通過類名直接訪問
3. final, finally, finalize的區(qū)別(或者說final庆冕、finalize 和 finally 的不同之處?)
final關(guān)鍵字可以用于類劈榨,方法访递,變量前,用來表示該關(guān)鍵字修飾的類同辣,方法拷姿,變量具有不可變的特性。
- final關(guān)鍵字用于基本數(shù)據(jù)類型前:這時(shí)表明該關(guān)鍵字修飾的變量是一個(gè)常量旱函,在定義后該變量的值就不能被修改响巢。
- final關(guān)鍵字用于方法聲明前:這時(shí)意味著該方法時(shí)最終方法,只能被調(diào)用棒妨,不能被覆蓋踪古,但是可以被重載。
- final關(guān)鍵字用于類名前:此時(shí)該類被稱為最終類,該類不能被其他類繼承伏穆。
finalize()
方法來自于java.lang.Object
拘泞,用于回收資源◎诔觯可以為任何一個(gè)類添加finalize方法田弥。finalize方法將在垃圾回收器清除對(duì)象之前調(diào)用。在實(shí)際應(yīng)用中铡原,不要依賴使用該方法回收任何短缺的資源偷厦,這是因?yàn)楹茈y知道這個(gè)方法什么時(shí)候被調(diào)用。
finally燕刻,當(dāng)代碼拋出一個(gè)異常時(shí)只泼,就會(huì)終止方法中剩余代碼的處理,并退出這個(gè)方法的執(zhí)行卵洗。finally塊是程序在正常情況下或異常情況下都會(huì)運(yùn)行的请唱。比較適合用于既要處理異常又有資源釋放的代碼,保證了資源的合理回收过蹂。
補(bǔ)充: try / catch / finally 中return的關(guān)系十绑?
1、不管有木有出現(xiàn)異常酷勺,finally塊中代碼都會(huì)執(zhí)行本橙;
2、當(dāng)try和catch中有return時(shí)脆诉,finally仍然會(huì)執(zhí)行甚亭;
3、finally是在return后面的表達(dá)式運(yùn)算后執(zhí)行的(此時(shí)并沒有返回運(yùn)算后的值击胜,而是先把要返回的值保存起來亏狰,管finally中的代碼怎么樣,返回的值都不會(huì)改變偶摔,仍然是之前保存的值)暇唾,所以函數(shù)返回值是在finally執(zhí)行前確定的;
4辰斋、finally中最好不要包含return信不,否則程序會(huì)提前退出,返回值不是try或catch中保存的返回值亡呵。
4. 能否在運(yùn)行時(shí)向 static final 類型的賦值
不可以,被static final
修飾的變量只能在被定義的時(shí)候或者類的靜態(tài)代碼塊中初始化硫戈,一旦賦值后就不能在改變了锰什。static final
相當(dāng)于類常量,就是在類被加載進(jìn)內(nèi)存的時(shí)候就要為屬性分配內(nèi)存,static
塊就是類被加載的時(shí)候執(zhí)行且被執(zhí)行一次汁胆,所以可以在其中進(jìn)行初始化梭姓。
5. 使用final關(guān)鍵字修飾一個(gè)變量時(shí),是引用不能變嫩码,還是引用的對(duì)象不能變?
是引用不能變(final引用恒定不變)誉尖,引用的對(duì)象內(nèi)容還是可以變的
8. throws, throw分別代表什么意義?
throw
是指的語句拋出一個(gè)異常,throws
指的是聲明方法可能拋出的異常類型
9铸题、Java 有幾種修飾符铡恕?分別用來修飾什么
類的修飾符:
-
public
可以在其他任何類中使用,默認(rèn)為統(tǒng)一包下的任意類丢间。 -
abstract
抽象類探熔,不能被實(shí)例化,可以包含抽象方法烘挫,抽象方法沒有被實(shí)現(xiàn)诀艰,無具體功能,只能衍生子類饮六。 -
final
不能被繼承其垄。
成員變量
-
訪問修飾符:
訪問修飾符 static
類變量:一個(gè)類所擁有的變量,不是類的每個(gè)實(shí)例有的變量卤橄。類變量是指不管類創(chuàng)建了多少對(duì)象绿满,系統(tǒng)僅在第一次調(diào)用類的時(shí)候?yàn)轭愖兞糠峙鋬?nèi)存,所有對(duì)象共享該類的類變量虽风,因此可以通過類本身或者某個(gè)對(duì)象來訪問類變量棒口。final
:常量。volatile
:聲明一個(gè)可能同時(shí)被并存運(yùn)行的幾個(gè)線程所控制和修改的變量辜膝。abstract
:只有聲明部分无牵,方法體為空,具體在子類中完成厂抖。transient
:(過度修飾符)指定該變量是系統(tǒng)保留智亮,暫無特別作用的臨時(shí)性變量。
方法修飾符:
- 訪問修飾符
public
(公共控制符)
private
(私有控制符)指定此方法只能有自己類等方法訪問统捶,其他的類不能訪問(包括子類)
protected
(保護(hù)訪問控制符)指定該方法可以被它的類和子類進(jìn)行訪問霉囚。 -
final
,指定該方法不能被重載墙懂。 -
static
橡卤,指定不需要實(shí)例化就可以激活的一個(gè)方法。 -
synchronize
损搬,同步修飾符碧库,在多個(gè)線程中柜与,該修飾符用于在運(yùn)行前,對(duì)他所屬的方法加鎖嵌灰,以防止其他線程的訪問弄匕,運(yùn)行結(jié)束后解鎖。 -
native
沽瞭,本地修飾符迁匠。指定此方法的方法體是用其他語言在程序外部編寫的。
volatile關(guān)鍵字
volatile
是一個(gè)特殊的修飾符,只有成員變量才能使用它吠架。在Java并發(fā)程序缺少同步類的情況下芙贫,多線程對(duì)成員變量的操作對(duì)其它線程是透明的。volatile變量可以保證下一個(gè)讀取操作會(huì)在前一個(gè)寫操作之后發(fā)生傍药,就是上一題的volatile變量規(guī)則磺平。
原理以及底層實(shí)現(xiàn)可參考:
《面試必問的 volatile,你了解多少拐辽?》
《volatile 關(guān)鍵字實(shí)現(xiàn)原理》匯編層面的講解拣挪,推薦!
1俱诸、volatile 修飾符的有過什么實(shí)踐
一種實(shí)踐是用 volatile
修飾 long
和 double
變量菠劝,使其能按原子類型來讀寫。double
和 long
都是64位寬睁搭,因此對(duì)這兩種類型的讀是分為兩部分的赶诊,第一次讀取第一個(gè) 32 位,然后再讀剩下的 32 位园骆,這個(gè)過程不是原子的舔痪,但 Java 中 volatile
型的 long
或double
變量的讀寫是原子的。volatile
修復(fù)符的另一個(gè)作用是提供內(nèi)存屏障(memory barrier)锌唾,例如在分布式框架中的應(yīng)用锄码。簡(jiǎn)單的說,就是當(dāng)你寫一個(gè) volatile
變量之前晌涕,Java 內(nèi)存模型會(huì)插入一個(gè)寫屏障(write barrier)滋捶,讀一個(gè) volatile 變量之前,會(huì)插入一個(gè)讀屏障(read barrier)余黎。意思就是說重窟,在你寫一個(gè)volatile
域時(shí),能保證任何線程都能看到你寫的值惧财,同時(shí)亲族,在寫之前炒考,也能保證任何數(shù)值的更新對(duì)所有線程是可見的,因?yàn)閮?nèi)存屏障會(huì)將其他所有寫的值更新到緩存霎迫。
2、volatile 變量是什么帘靡?volatile 變量和 atomic 變量有什么不同
Java語言提供了一種稍弱的同步機(jī)制知给,即volatile
變量,用來確保將變量的更新操作通知到其他線程描姚。當(dāng)把變量聲明為volatile
類型后涩赢,編譯器與運(yùn)行時(shí)都會(huì)注意到這個(gè)變量是共享的,因此不會(huì)將該變量上的操作與其他內(nèi)存操作一起重排序轩勘。volatile
變量不會(huì)被緩存在寄存器或者對(duì)其他處理器不可見的地方筒扒,因此在讀取volatile
類型的變量時(shí)總會(huì)返回最新寫入的值。
在訪問volatile
變量時(shí)不會(huì)執(zhí)行加鎖操作绊寻,因此也就不會(huì)使執(zhí)行線程阻塞花墩,因此volatile
變量是一種比sychronized
關(guān)鍵字更輕量級(jí)的同步機(jī)制。
3澄步、volatile 類型變量提供什么保證冰蘑?能使得一個(gè)非原子操作變成原子操作嗎?
volatile只提供了保證訪問該變量時(shí),每次都是從內(nèi)存中讀取最新值村缸,并不會(huì)使用寄存器緩存該值——每次都會(huì)從內(nèi)存中讀取祠肥。而對(duì)該變量的修改,volatile
并不提供原子性的保證梯皿。那么編譯器究竟是直接修改內(nèi)存的值仇箱,還是使用寄存器修改都符合volatile的定義。所以东羹,一句話剂桥,volatile
并不提供原子性的保證。
一個(gè)典型的例子是在類中有一個(gè) long 類型的成員變量百姓。如果你知道該成員變量會(huì)被多個(gè)線程訪問渊额,如計(jì)數(shù)器、價(jià)格等垒拢,你最好是將其設(shè)置為 volatile旬迹。為什么?因?yàn)?Java 中讀取 long 類型變量不是原子的求类,需要分成兩步奔垦,如果一個(gè)線程正在修改該 long 變量的值,另一個(gè)線程可能只能看到該值的一半(前 32 位)尸疆。但是對(duì)一個(gè) volatile 型的 long 或 double 變量的讀寫是原子椿猎。
補(bǔ)充另外一種思路:volatile 類型變量提供什么保證惶岭?
volatile
變量提供順序和可見性保證,例如犯眠,JVM 或者 JIT為了獲得更好的性能會(huì)對(duì)語句重排序按灶,但是 volatile
類型變量即使在沒有同步塊的情況下賦值也不會(huì)與其他語句重排序。 volatile
提供happens-before
的保證筐咧,確保一個(gè)線程的修改能對(duì)其他線程是可見的鸯旁。某些情況下,volatile
還能提供原子性量蕊,如讀 64 位數(shù)據(jù)類型铺罢,像 long 和 double 都不是原子的,但 volatile
類型的 double
和long
就是原子的残炮。
4韭赘、能創(chuàng)建 volatile 數(shù)組嗎?
可以势就,volatile
修飾的變量如果是對(duì)象或數(shù)組之類的泉瞻,其含義是對(duì)象獲數(shù)組的地址具有可見性,但是數(shù)組或?qū)ο髢?nèi)部的成員改變不具備可見性蛋勺。
換句話說就是:Java 中可以創(chuàng)建 volatile
類型數(shù)組瓦灶,不過只是一個(gè)指向數(shù)組的引用,而不是整個(gè)數(shù)組抱完。如果改變引用指向的數(shù)組贼陶,將會(huì)受到volatile
的保護(hù),但是如果多個(gè)線程同時(shí)改變數(shù)組的元素巧娱,volatile
標(biāo)示符就不能起到之前的保護(hù)作用了碉怔。
5、transient變量有什么特點(diǎn)?
- 一旦變量被
transient
修飾禁添,變量將不再是對(duì)象持久化的一部分撮胧,該變量?jī)?nèi)容在序列化后無法獲得訪問。 -
transient
關(guān)鍵字只能修飾變量老翘,而不能修飾方法和類芹啥。注意,本地變量是不能被transient
關(guān)鍵字修飾的铺峭。變量如果是用戶自定義類變量墓怀,則該類需要實(shí)現(xiàn)Serializable接口。 - 被
transient
關(guān)鍵字修飾的變量不能被序列化卫键,一個(gè)靜態(tài)變量不管是否被transient修飾傀履,均不能被序列化。
6莉炉、super什么時(shí)候使用?
super主要存在于子類方法中钓账,用于指向子類對(duì)象中父類對(duì)象碴犬。
1:訪問父類的屬性
2:訪問父類的函數(shù)
3:訪問父類的構(gòu)造函數(shù)
7、public static void 寫成 static public void會(huì)怎樣?
一樣的
8梆暮、說明一下public static void main(String args[])這段聲明里每個(gè)關(guān)鍵字的作用?
主函數(shù)是什么:主函數(shù)是一個(gè)特殊的函數(shù)服协,作為程序的入口,可以被jvm識(shí)別啦粹。
主函數(shù)的定義:
-
public
:代表該函數(shù)的訪問權(quán)限是最大的蚯涮。 -
static
:代表主函數(shù)隨著類的加載,就已經(jīng)存在了卖陵。 -
void
: 主函數(shù)沒有具體的返回值 -
main
: 不是關(guān)鍵字,是一個(gè)特殊的單詞可以被jvm識(shí)別张峰。 -
(String[] args)
函數(shù)的參數(shù)泪蔫,參數(shù)類型是一個(gè)數(shù)組,該數(shù)組中的元素是字符串喘批。字符串類型的數(shù)組撩荣。
主函數(shù)的格式是固定的:jvm能夠識(shí)別
9、sizeof 是Java 的關(guān)鍵字嗎?
不是饶深,C和C++用sizeof()
解決移植問題餐曹,java不需要。
static關(guān)鍵字
1敌厘、static class 與 non static class的區(qū)別
靜態(tài)變量跟實(shí)例變量的區(qū)別:
- 靜態(tài)變量:由static修飾台猴,在JVM中,靜態(tài)變量的加載順序在對(duì)象之前俱两,因此靜態(tài)變量不依附于對(duì)象存在饱狂,可以在不實(shí)例化類的情況下直接使用靜態(tài)變量。靜態(tài)變量屬于類宪彩,不屬于類中任何一個(gè)對(duì)象休讳,因此靜態(tài)變量又叫做類變量,一個(gè)類不管創(chuàng)建多少個(gè)對(duì)象(對(duì)象是類的一個(gè)實(shí)例)尿孔,靜態(tài)變量在內(nèi)存中有且僅有一個(gè)俊柔。
- 實(shí)例變量:必須依附于對(duì)象存在,只有實(shí)例化類后才可以使用此類中的實(shí)例變量活合。
靜態(tài)方法跟實(shí)例方法的區(qū)別:
- 靜態(tài)方法:方法用static關(guān)鍵字修飾雏婶,靜態(tài)方法與靜態(tài)成員變量一樣,屬于類本身芜辕,在類裝載的時(shí)候被裝載到內(nèi)存尚骄,不自動(dòng)進(jìn)行銷毀,會(huì)一直存在于內(nèi)存中侵续,直到JVM關(guān)閉倔丈。使用時(shí)也是不需要實(shí)例化類憨闰,能夠直接使用。靜態(tài)方法無法被重寫需五。需要注意的是:在靜態(tài)方法中只能訪問類中的靜態(tài)成員跟靜態(tài)方法鹉动,不能直接訪問類中的實(shí)例變量跟實(shí)例方法
- 實(shí)例化方法:屬于實(shí)例對(duì)象,實(shí)例化后才會(huì)分配內(nèi)存宏邮,必須通過類的實(shí)例來引用泽示。不會(huì)常駐內(nèi)存,當(dāng)實(shí)例對(duì)象被JVM 回收之后蜜氨,也跟著消失械筛。
線程安全和效率說明:
- 線程安全:靜態(tài)方法是共享代碼段,靜態(tài)變量是共享數(shù)據(jù)段飒炎。既然是“共享”就有并發(fā)的問題埋哟。非靜態(tài)方法是針對(duì)確定的一個(gè)對(duì)象的,所以不會(huì)存在線程安全的問題郎汪。
- 如果靜態(tài)方法在系統(tǒng)中定義太多赤赊,會(huì)占用大量的資源,最后造成內(nèi)存溢出煞赢,所以靜態(tài)方法不能濫用抛计。
2、static 關(guān)鍵字是什么意思照筑?Java中是否可以覆蓋(override)一個(gè)private或者是static的方法吹截,靜態(tài)類型有什么特點(diǎn)?
static
表示靜態(tài)的意思朦肘,可用于修飾成員變量和成員函數(shù)饭弓,被靜態(tài)修飾的成員函數(shù)只能訪問靜態(tài)成員,不可以訪問非靜態(tài)成員媒抠。靜態(tài)是隨著類的加載而加載的弟断,因此可以直接用類進(jìn)行訪問。 重寫是子類中的方法和子類繼承的父類中的方法一樣(函數(shù)名趴生,參數(shù)阀趴,參數(shù)類型,反回值類型)苍匆,但是子類中的訪問權(quán)限要不低于父類中的訪問權(quán)限刘急。重寫的前提是必須要繼承,private
修飾不支持繼承浸踩,因此被私有的方法不可以被重寫叔汁。在Java中,如果父類中含有一個(gè)靜態(tài)方法,且在子類中也含有一個(gè)返回類型据块、方法名码邻、參數(shù)列表均與之相同的靜態(tài)方法,那么該子類實(shí)際上只是將父類中的該同名方法進(jìn)行了隱藏另假,而非重寫像屋。換句話說,父類和子類中含有的其實(shí)是兩個(gè)沒有關(guān)系的方法边篮,它們的行為也并不具有多態(tài)性己莺。
針對(duì)繼承中private的問題:
子類繼承了父類的所有屬性和方法或子類擁有父類的所有屬性和方法是對(duì)的,只不過父類的私有屬性和方法戈轿,子類是無法直接訪問到的凌受。即只是擁有,但是無法使用思杯。當(dāng)然私有屬性可以通過public修飾的getter和setter方法訪問到的胁艰,但是私有方法不行。
3智蝠、main() 方法為什么必須是靜態(tài)的?能不能聲明 main() 方法為非靜態(tài)奈梳?
用static
修飾的就是靜態(tài)方法杈湾。靜態(tài)方法不依靠對(duì)象而存在。其直接與類有關(guān)攘须,只要包含在類中漆撞,就可以得到執(zhí)行,而不一定依附于對(duì)象的存在而執(zhí)行于宙。因此浮驳,main
方法作為程序的入口方法,在這之前是不可能有任何對(duì)象被建立的捞魁,也就在main
之前包括main
自身不可能是非靜態(tài)方法至会。所以main
方法一定是靜態(tài)的,有類就行——從而得到執(zhí)行谱俭,進(jìn)而有更多靜態(tài)或非靜態(tài)方法得到執(zhí)行奉件。
4、是否可以從一個(gè)靜態(tài)(static)方法內(nèi)部發(fā)出對(duì)非靜態(tài)(non-static)方法的調(diào)用
不可以昆著,靜態(tài)函數(shù)中不能訪問非靜態(tài)成員變量县貌,只能訪問靜態(tài)變量。因?yàn)殪o態(tài)優(yōu)先于對(duì)象存在.靜態(tài)方法中更不可以出現(xiàn)this
5凑懂、靜態(tài)變量在什么時(shí)候加載煤痕?編譯期還是運(yùn)行期?靜態(tài)代碼塊加載的時(shí)機(jī)呢?
靜態(tài)是隨著類的加載而加載的摆碉,JVM的代碼編譯運(yùn)行順序是編譯塘匣、類的加載到執(zhí)行,屬于二者的過渡期兆解。靜態(tài)代碼塊也是如此馆铁。
6、成員方法是否可以訪問靜態(tài)變量锅睛?為什么靜態(tài)方法不能訪問成員變量埠巨?
成員方法中可以訪問靜態(tài)成員變量。
請(qǐng)看下面代碼來確定程序的打印先后順序:
public class test {
public static void main(String[] args) {
new test();
}
static int num = 4;
{
num += 3;
System.out.println(b);
}
int a = 5;
{
System.out.println(c);
}
test() {System.out.println(d);}
static {System.out.println(a);}
static void run() {System.out.println(e);}
}
執(zhí)行順序如下:
public class test { 1.第一步现拒,準(zhǔn)備加載類
public static void main(String[] args) {
new test(); 4.第四步辣垒,new一個(gè)類,但在new之前要處理匿名代碼塊
}
static int num = 4; 2.第二步印蔬,靜態(tài)變量和靜態(tài)代碼塊的加載順序由編寫先后決定
{
num += 3;
System.out.println(b);5.第五步勋桶,按照順序加載匿名代碼塊,代碼塊中有打印
}
int a = 5; 6.第六步侥猬,按照順序加載變量
{ 成員變量第三個(gè)
System.out.println(c); 7.第七步例驹,按照順序打印c
}
如果將構(gòu)造函數(shù)和構(gòu)造代碼塊呼喚,依舊還是先執(zhí)行構(gòu)造代碼塊退唠。
test() { 類的構(gòu)造函數(shù)鹃锈,第四個(gè)加載
System.out.println(d); 8.第八步,最后加載構(gòu)造函數(shù)瞧预,完成對(duì)象的建立
}
static { 3.第三步屎债,靜態(tài)塊,然后執(zhí)行靜態(tài)代碼塊垢油,因?yàn)橛休敵雠杈裕蚀蛴
System.out.println(a);
}
static void run() 靜態(tài)方法隨類加載,調(diào)用的時(shí)候才執(zhí)行 注意看滩愁,e沒有加載
{
System.out.println(e);
}
}
靜態(tài)塊(靜態(tài)變量)——成員變量——構(gòu)造方法——靜態(tài)方法
1躯喇、靜態(tài)代碼塊(只加載一次) 2、構(gòu)造方法(創(chuàng)建一個(gè)實(shí)例就加載一次)3硝枉、靜態(tài)方法需要調(diào)用才會(huì)執(zhí)行.
如果類還沒有被加載:
- 1玖瘸、先執(zhí)行父類的靜態(tài)代碼塊和靜態(tài)變量初始化,并且靜態(tài)代碼塊和靜態(tài)變量的執(zhí)行順序只跟代碼中出現(xiàn)的順序有關(guān)檀咙。
- 2雅倒、執(zhí)行子類的靜態(tài)代碼塊和靜態(tài)變量初始化。
- 3弧可、執(zhí)行父類的實(shí)例變量初始化
- 4蔑匣、執(zhí)行父類的構(gòu)造函數(shù)(有構(gòu)造代碼塊則先執(zhí)行構(gòu)造代碼塊)
- 5劣欢、執(zhí)行子類的實(shí)例變量初始化
- 6、執(zhí)行子類的構(gòu)造函數(shù)
如果類已經(jīng)被加載:
則靜態(tài)代碼塊和靜態(tài)變量就不用重復(fù)執(zhí)行裁良,再創(chuàng)建類對(duì)象時(shí)凿将,只執(zhí)行與實(shí)例相關(guān)的變量初始化和構(gòu)造方法。
補(bǔ)充構(gòu)造代碼塊:給對(duì)象進(jìn)行初始化价脾。對(duì)象一建立就運(yùn)行并且優(yōu)先于構(gòu)造函數(shù)牧抵。
構(gòu)造代碼塊和構(gòu)造函數(shù)的區(qū)別,構(gòu)造代碼塊是給所有對(duì)象進(jìn)行統(tǒng)一初始化侨把, 構(gòu)造函數(shù)給對(duì)應(yīng)的對(duì)象初始化犀变。
關(guān)于類的加載可以重點(diǎn)參考:
switch關(guān)鍵字
1、switch 語句中的表達(dá)式可以是什么類型數(shù)據(jù)秋柄?
switch(A),括號(hào)中A的取值可以是byte
获枝、short
、int
骇笔、char
省店、String
,還有枚舉類型笨触。
2懦傍、switch 是否能作用在byte 上,是否能作用在long 上芦劣,是否能作用在String上谎脯?
Java 7之前,switch后面的括號(hào)里面只能放int類型的值持寄,注意是只能放int類型,但是放byte娱俺,short稍味,char類型的也可以,是因?yàn)閎yte荠卷,short模庐,shar可以自動(dòng)提升(自動(dòng)類型轉(zhuǎn)換)為int,不是說就可以放它們油宜,說白了掂碱,你放的byte,short慎冤,shar類型疼燥,然后他們會(huì)自動(dòng)轉(zhuǎn)換為int類型(寬化,自動(dòng)轉(zhuǎn)換并且安全)蚁堤,其實(shí)最后放的還是int類型醉者。String可以了,但是long仍然不行。
1.小的往大的轉(zhuǎn)換(寬化)撬即,自動(dòng)轉(zhuǎn)換立磁,有些時(shí)候就會(huì)自動(dòng)提升為大的類型,比如switch中
2.大的往小的轉(zhuǎn)換(窄化)必須強(qiáng)制類型轉(zhuǎn)換所以long不行剥槐,要想行就得強(qiáng)轉(zhuǎn)如(int)long唱歧。同理,float粒竖、double也是不行的颅崩,要想行就強(qiáng)轉(zhuǎn)。
3温圆、while 循環(huán)和 do 循環(huán)有什么不同挨摸?
while
語法格式:
while(布爾表達(dá)式){
//語句
}
先判斷布爾表達(dá)式,如果為true就會(huì)執(zhí)行循環(huán)體中的語句岁歉,然后再判斷布爾表達(dá)式得运,如果為true就執(zhí)行循環(huán)體中的語句,一直到布爾表達(dá)式為false锅移,然后循環(huán)結(jié)束熔掺。通常用算術(shù)運(yùn)算符(++ -- 累減)
do/while
語法格式:
do{
//語句
}while(布爾表達(dá)式);
先執(zhí)行一次循環(huán)體,然后在判斷布爾表達(dá)式是不是true非剃,如果是就繼續(xù)執(zhí)行循環(huán)體置逻,在判斷布爾表達(dá)式,直到為false就結(jié)束循環(huán)备绽。
兩者的區(qū)別:while
是先判斷在執(zhí)行如果判斷不成立券坞,就不會(huì)執(zhí)行;do/while
是先執(zhí)行在判斷肺素,不管判斷是否成立都會(huì)執(zhí)行一次
操作符
1恨锚、&操作符和&&操作符有什么區(qū)別
&&
運(yùn)算符是短路與運(yùn)算倍靡。邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運(yùn)算符左右兩端的布爾值都是true整個(gè)表達(dá)式的值才是true塌西。&&
之所以稱為短路運(yùn)算是因?yàn)椋绻?code>&&左邊的表達(dá)式的值是false捡需,右邊的表達(dá)式會(huì)被直接短路掉办桨,不會(huì)進(jìn)行運(yùn)算。很多時(shí)候我們可能都需要用&&
而不是&
站辉。
2崔挖、a = a + b 與 a += b 的區(qū)別贸街?
★ =:賦值運(yùn)算符,在編譯器將右邊的表達(dá)式結(jié)果計(jì)算出來后狸相,和左邊的變量類型比較精度薛匪,如果左邊的變量精度低于右邊的結(jié)果的精度,編譯器會(huì)顯式的報(bào)錯(cuò)脓鹃,告訴程序員去強(qiáng)制轉(zhuǎn)型逸尖。(若a精度類型弱于b,a = a + b出錯(cuò)瘸右,編譯檢查報(bào)錯(cuò))最后將表達(dá)式的結(jié)果復(fù)制到變量所在的內(nèi)存區(qū)娇跟。
★ +=:暫且稱之為運(yùn)算符,編譯器自動(dòng)隱式直接將+=運(yùn)算符后面的操作數(shù)強(qiáng)制裝換為前面變量的類型太颤,然后在變量所在的內(nèi)存區(qū)上直接根據(jù)右邊的操作數(shù)修改左邊變量?jī)?nèi)存存儲(chǔ)的二進(jìn)制數(shù)值最后達(dá)到和賦值運(yùn)算符相同的目的苞俘。與前者相比,由于后者是位操作龄章,效率也較前者高吃谣。
3、30.1 == 0.3 將會(huì)返回什么做裙?true 還是 false岗憋?
False,類型不一致锚贱。
4仔戈、float f=3.4; 是否正確?
不正確拧廊。3.4
是雙精度數(shù)监徘,將雙精度型(double)賦值給浮點(diǎn)型(float)屬于下轉(zhuǎn)型(down-casting,也稱為窄化)會(huì)造成精度損失吧碾,因此需要強(qiáng)制類型轉(zhuǎn)換float f =(float)3.4
; 或者寫成float f =3.4F;
凰盔。
5、short s1 = 1; s1 = s1 + 1;有錯(cuò)嗎?short s1 = 1; s1 += 1;有錯(cuò)嗎滤港?
對(duì)于short s1 = 1; s1 = s1 + 1;
由于1是int
類型溅漾,因此s1+1
運(yùn)算結(jié)果也是int
型添履,需要強(qiáng)制轉(zhuǎn)換類型才能賦值給short
型暮胧。而short s1 = 1; s1 += 1;
可以正確編譯,因?yàn)?code>s1+= 1;相當(dāng)于s1 = (short)(s1 + 1);
其中有隱含的強(qiáng)制類型轉(zhuǎn)換钞翔。