1、一個".java"源文件中是否可以包括多個類(不是內(nèi)部類)锰悼?有什么限制柳骄?
????????可以有多個類,但只能有一個public的類箕般,并且public的類名必須與文件名相一致耐薯。
2、Java有沒有g(shù)oto?
????????java中的保留字丝里,現(xiàn)在沒有在java中使用曲初。
3、說說&和&&的區(qū)別杯聚。
????????&和&&都可以用作邏輯與的運算符臼婆,表示邏輯與(and),當運算符兩邊的表達式的結(jié)果都為true時幌绍,整個運算結(jié)果才為true颁褂,否則,只要有一方為false傀广,則結(jié)果為false痢虹。
????????&&還具有短路的功能,即如果第一個表達式為false主儡,則不再計算第二個表達式奖唯,例如,對于if(str!= null&& !str.equals(s))表達式糜值,當str為null時丰捷,后面的表達式不會執(zhí)行,所以不會出現(xiàn)NullPointerException如果將&&改為&寂汇,則會拋出NullPointerException異常病往。If(x==33 &++y>0) y會增長,If(x==33 && ++y>0)不會增長
????????&還可以用作位運算符骄瓣,當&操作符兩邊的表達式不是boolean類型時停巷,&表示按位與操作,我們通常使用0x0f來與一個整數(shù)進行&運算,來獲取該整數(shù)的最低4個bit位畔勤,例如蕾各,0x31 & 0x0f的結(jié)果為0x01。
4庆揪、在JAVA中如何跳出當前的多重嵌套循環(huán)式曲?
????????在Java中,要想跳出多重循環(huán)缸榛,可以在外面的循環(huán)語句前定義一個標號吝羞,然后在里層循環(huán)體的代碼中使用帶有標號的break語句,即可跳出外層循環(huán)内颗。
例如:
for(int i=0;i<10;i++){
????????for(intj=0;j<10;j++){
????????????????????System.out.println(“i=” + i + “,j=” + j);
? ? ? ? ????? ?????if(j == 5) break ok;
????????}
}
????????另外钧排,我個人通常并不使用標號這種方式,而是讓外層的循環(huán)條件表達式的結(jié)果可以受到里層循環(huán)體代碼的控制均澳,例如卖氨,要在二維數(shù)組中查找到某個數(shù)字。
int arr[][] ={{1,2,3},{4,5,6,7},{9}};
boolean found = false;
for(int i=0;i<arr.length&&!found;i++)?????? {
??????? for(intj=0;j<arr[i].length;j++){
??????????????System.out.println(“i=” + i + “,j=” + j);
??????????????if(arr[i][j]?==5) {
????????????????????? found =true;
????????????????????? break;
??????????????}
??????? }
}
5负懦、switch語句能否作用在byte上筒捺,能否作用在long上,能否作用在String上?
????????在switch(e)中纸厉,e只能是一個整數(shù)表達式或者枚舉常量(更大字體)系吭,整數(shù)表達式可以是int基本類型或Integer包裝類型,由于byte,short,char都可以隱含轉(zhuǎn)換為int颗品,所以肯尺,這些類型以及這些類型的包裝類型也是可以的。顯然躯枢,long和String類型都不符合switch的語法規(guī)定则吟,并且不能被隱式轉(zhuǎn)換成int類型,所以锄蹂,它們不能作用于swtich語句中氓仲。
6、short s1= 1; s1 = (s1+1是int類型得糜,而等號左邊的是short類型敬扛,所以需要強轉(zhuǎn))1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯?(沒有錯)
????????對于short s1= 1; s1 = s1 + 1;由于s1+1運算時會自動提升表達式的類型,所以結(jié)果是int型朝抖,再賦值給short類型s1時啥箭,編譯器將報告需要強制轉(zhuǎn)換類型的錯誤。
????????對于short s1= 1; s1 += 1;由于 +=是java語言規(guī)定的運算符治宣,java編譯器會對它進行特殊處理急侥,因此可以正確編譯砌滞。
7、char型變量中能不能存貯一個中文漢字?為什么?
????????char型變量是用來存儲Unicode編碼的字符的坏怪,unicode編碼字符集中包含了漢字贝润,所以,char型變量中當然可以存儲漢字啦陕悬。不過,如果某個特殊的漢字沒有被包含在unicode編碼字符集中按傅,那么捉超,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼占用兩個字節(jié)唯绍,所以拼岳,char類型的變量也是占用兩個字節(jié)。
8况芒、用最有效率的方法算出2乘以8等於幾?
????????2<< 3惜纸,(左移三位)因為將一個數(shù)左移n位,就相當于乘以了2的n次方绝骚,那么耐版,一個數(shù)乘以8只要將其左移3位即可,而位運算cpu直接支持的压汪,效率最高粪牲,所以,2乘以8等於幾的最效率的方法是2<< 3止剖。
9腺阳、使用final關(guān)鍵字修飾一個變量時,是引用不能變穿香,還是引用的對象不能變亭引?
????????使用final關(guān)鍵字修飾一個變量時,是指引用變量不能變皮获,引用變量所指向的對象中的內(nèi)容還是可以改變的焙蚓。例如,對于如下語句:
?finalStringBuffer a=new StringBuffer("immutable");
執(zhí)行如下語句將報告編譯期錯誤:
a=new StringBuffer("");
但是洒宝,執(zhí)行如下語句則可以通過編譯:
a.append(" broken!");
有人在定義方法的參數(shù)時主届,可能想采用如下形式來阻止方法內(nèi)部修改傳進來的參數(shù)對象:
public void method(final? StringBuffer param){
}
實際上,這是辦不到的待德,在該方法內(nèi)部仍然可以增加如下代碼來修改參數(shù)對象:
?param.append("a");
10君丁,靜態(tài)變量和實例變量的區(qū)別?
????????在語法定義上的區(qū)別:靜態(tài)變量前要加static關(guān)鍵字将宪,而實例變量前則不加绘闷。
????????在程序運行時的區(qū)別:實例變量屬于某個對象的屬性橡庞,必須創(chuàng)建了實例對象,其中的實例變量才會被分配空間印蔗,才能使用這個實例變量扒最。靜態(tài)變量不屬于某個實例對象,而是屬于類华嘹,所以也稱為類變量吧趣,只要程序加載了類的字節(jié)碼,不用創(chuàng)建任何實例對象耙厚,靜態(tài)變量就會被分配空間强挫,靜態(tài)變量就可以被使用了⊙總之俯渤,實例變量必須創(chuàng)建對象后才可以通過這個對象來使用,靜態(tài)變量則可以直接使用類名來引用型宝。
????????例如八匠,對于下面的程序,無論創(chuàng)建多少個實例對象趴酣,永遠都只分配了一個staticVar變量梨树,并且每創(chuàng)建一個實例對象,這個staticVar就會加1岖寞;但是劝萤,每創(chuàng)建一個實例對象,就會分配一個instanceVar慎璧,即可能分配多個instanceVar床嫌,并且每個instanceVar的值都只自加了1次。
public class VariantTest{
??????? publicstatic int staticVar = 0;
??????? publicint instanceVar = 0;
??????? publicVariantTest(){
??????????????staticVar++;
??????????????instanceVar++;
??????????????System.out.println(staticVar +instanceVar);
??????? }
}
11胸私、是否可以從一個static方法內(nèi)部發(fā)出對非static方法的調(diào)用厌处?
????????不可以。因為非static方法是要與對象關(guān)聯(lián)在一起的岁疼,必須創(chuàng)建一個對象后阔涉,才可以在該對象上進行方法調(diào)用,而static方法調(diào)用時不需要創(chuàng)建對象捷绒,可以直接調(diào)用瑰排。也就是說,當一個static方法被調(diào)用時暖侨,可能還沒有創(chuàng)建任何實例對象椭住,如果從一個static方法中發(fā)出對非static方法的調(diào)用,那個非static方法是關(guān)聯(lián)到哪個對象上的呢字逗?這個邏輯無法成立京郑,所以宅广,一個static方法內(nèi)部發(fā)出對非static方法的調(diào)用。
12些举、Integer與int的區(qū)別
????????int是java提供的8種原始數(shù)據(jù)類型之一跟狱。Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類户魏。int的默認值為0驶臊,而Integer的默認值為null,即Integer可以區(qū)分出未賦值和值為0的區(qū)別叼丑,int則無法表達出未賦值的情況关翎。
????????例如:要想表達出沒有參加考試和考試成績?yōu)?的區(qū)別,則只能使用Integer幢码。在JSP開發(fā)中笤休,Integer的默認為null尖飞,所以用el表達式在文本框中顯示時症副,值為空白字符串,而int默認的默認值為0政基,所以用el表達式在文本框中顯示時贞铣,結(jié)果為0,所以沮明,int不適合作為web層的表單數(shù)據(jù)的類型辕坝。
????????在Hibernate中,如果將OID定義為Integer類型荐健,那么Hibernate就可以根據(jù)其值是否為null而判斷一個對象是否是臨時的酱畅,如果將OID定義為了int類型,還需要在hbm映射文件中設(shè)置其unsaved-value屬性為0江场。
????????另外纺酸,Integer提供了多個與整數(shù)相關(guān)的操作方法,例如址否,將一個字符串轉(zhuǎn)換成整數(shù)餐蔬,Integer中還定義了表示整數(shù)的最大值和最小值的常量。
13佑附、Math.round(11.5)等於多少?Math.round(-11.5)等於多少?
????????Math類中提供了三個與取整有關(guān)的方法:ceil樊诺、floor、round音同,這些方法的作用與它們的英文名稱的含義相對應(yīng)词爬。
????????例如,ceil的英文意義是天花板权均,該方法就表示向上取整缸夹,Math.ceil(11.3)的結(jié)果為12,Math.ceil(-11.3)的結(jié)果是-11痪寻;floor的英文意義是地板,該方法就表示向下取整虽惭,Math.ceil(11.6)的結(jié)果為11,Math.ceil(-11.6)的結(jié)果是-12橡类;最難掌握的是round方法,它表示“四舍五入”芽唇,算法為Math.floor(x+0.5)顾画,即將原來的數(shù)字加上0.5后再向下取整,所以匆笤,Math.round(11.5)的結(jié)果為12研侣,Math.round(-11.5)的結(jié)果為-11。
14炮捧、Overload和Override的區(qū)別庶诡?Overloaded的方法是否可以改變返回值的類型?
????????Overload是重載的意思,Override是覆蓋的意思咆课,也就是重寫末誓。
????????重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數(shù)列表各不相同(即參數(shù)個數(shù)或類型不同)书蚪。
????????重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數(shù)完全相同喇澡,通過子類創(chuàng)建的實例對象調(diào)用這個方法時,將調(diào)用子類中的定義方法殊校,這相當于把父類中定義的那個完全相同的方法給覆蓋了晴玖,這也是面向?qū)ο缶幊痰亩鄳B(tài)性的一種表現(xiàn)。子類覆蓋父類的方法時为流,只能比父類拋出更少的異常呕屎,或者是拋出父類拋出的異常的子異常,因為子類可以解決父類的一些問題敬察,不能比父類有更多的問題秀睛。子類方法的訪問權(quán)限只能比父類的更大,不能更小静汤。如果父類的方法是private類型琅催,那么,子類則不存在覆蓋的限制虫给,相當于子類中增加了一個全新的方法藤抡。
????????至于Overloaded的方法是否可以改變返回值的類型這個問題,要看你倒底想問什么呢抹估?這個題目很模糊缠黍。如果幾個Overloaded的方法的參數(shù)列表不一樣,它們的返回者類型當然也可以不一樣药蜻。但我估計你想問的問題是:如果兩個方法的參數(shù)列表完全一樣瓷式,是否可以讓它們的返回值不同來實現(xiàn)重載Overload替饿。這是不行的,我們可以用反證法來說明這個問題贸典,因為我們有時候調(diào)用一個方法時也可以不定義返回結(jié)果變量视卢,即不要關(guān)心其返回結(jié)果,例如廊驼,我們調(diào)用map.remove(key)方法時据过,雖然remove方法有返回值,但是我們通常都不會定義接收返回結(jié)果的變量妒挎,這時候假設(shè)該類中有兩個名稱和參數(shù)列表完全相同的方法绳锅,僅僅是返回類型不同,java就無法確定編程者倒底是想調(diào)用哪個方法了酝掩,因為它無法通過返回結(jié)果類型來判斷鳞芙。
????????override可以翻譯為覆蓋,從字面就可以知道期虾,它是覆蓋了一個方法并且對其重寫原朝,以求達到不同的作用。對我們來說最熟悉的覆蓋就是對接口方法的實現(xiàn)彻消,在接口中一般只是對方法進行了聲明竿拆,而我們在實現(xiàn)時宙拉,就需要實現(xiàn)接口聲明的所有方法宾尚。除了這個典型的用法以外,我們在繼承中也可能會在子類覆蓋父類中的方法谢澈。在覆蓋要注意以下的幾點:
????????1煌贴、覆蓋的方法的標志必須要和被覆蓋的方法的標志完全匹配,才能達到覆蓋的效果锥忿;
????????2牛郑、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;
????????3敬鬓、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致淹朋,或者是其子類;
????????4钉答、被覆蓋的方法不能為private础芍,否則在其子類中只是新定義了一個方法,并沒有對其進行覆蓋数尿。
????????Overload對我們來說可能比較熟悉仑性,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法右蹦,通過定義不同的輸入?yún)?shù)來區(qū)分這些方法诊杆,然后再調(diào)用時歼捐,VM就會根據(jù)不同的參數(shù)樣式,來選擇合適的方法執(zhí)行晨汹。在使用重載要注意以下的幾點:
????????1豹储、在使用重載時只能通過不同的參數(shù)樣式。例如淘这,不同的參數(shù)類型颂翼,不同的參數(shù)個數(shù),不同的參數(shù)順序(當然慨灭,同一方法內(nèi)的幾個參數(shù)類型必須不一樣朦乏,例如可以是fun(int,float),但是不能為fun(int,int))氧骤;
????????2呻疹、不能通過訪問權(quán)限、返回類型、拋出的異常進行重載;
????????3伶丐、方法的異常類型和數(shù)目不會對重載造成影響硝全;
????????4、對于繼承來說蕊肥,如果某一方法在父類中是訪問權(quán)限是priavte,那么就不能在子類對其進行重載,如果定義的話宋彼,也只是定義了一個新方法,而不會達到重載的效果仙畦。
15输涕、接口是否可繼承接口?抽象類是否可實現(xiàn)(implements)接口?抽象類是否可繼承具體類(concreteclass)?抽象類中是否可以有靜態(tài)的main方法?
????????接口可以繼承接口慨畸。抽象類可以實現(xiàn)(implements)接口莱坎,抽象類可以繼承具體類。抽象類中可以有靜態(tài)的main方法寸士。
????????備注:只要明白了接口和抽象類的本質(zhì)和作用檐什,這些問題都很好回答,你想想弱卡,如果你是java語言的設(shè)計者乃正,你是否會提供這樣的支持,如果不提供的話谐宙,有什么理由嗎烫葬?如果你沒有道理不提供,那答案就是肯定的了。
????????只要記住抽象類與普通類的唯一區(qū)別就是不能創(chuàng)建實例對象和允許有abstract方法搭综。
16垢箕、Java中實現(xiàn)多態(tài)的機制是什么?
????????靠的是父類或接口定義的引用變量可以指向子類或具體實現(xiàn)類的實例對象兑巾,而程序調(diào)用的方法在運行期才動態(tài)綁定条获,就是引用變量所指向的具體實例對象的方法,也就是內(nèi)存里正在運行的那個對象的方法蒋歌,而不是引用變量的類型中定義的方法帅掘。
17、abstractclass和interface語法上有什么區(qū)別?
1.抽象類可以有構(gòu)造方法堂油,接口中不能有構(gòu)造方法修档。
2.抽象類中可以有普通成員變量,接口中沒有普通成員變量
3.抽象類中可以包含非抽象的普通方法府框,接口中的所有方法必須都是抽象的吱窝,不能有非抽象的普通方法。
4. 抽象類中的抽象方法的訪問類型可以是public迫靖,protected和(默認類型,雖然
eclipse下不報錯院峡,但應(yīng)該也不行),但接口中的抽象方法只能是public類型的系宜,并且默認即為public abstract類型照激。
5. 抽象類中可以包含靜態(tài)方法,接口中不能包含靜態(tài)方法
6. 抽象類和接口中都可以包含靜態(tài)成員變量盹牧,抽象類中的靜態(tài)成員變量的訪問類型可以任意俩垃,但接口中定義的變量只能是publicstatic final類型,并且默認即為publicstatic final類型欢策。
7. 一個類可以實現(xiàn)多個接口吆寨,但只能繼承一個抽象類赏淌。
18踩寇、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
????????abstract的method不可以是static的六水,因為抽象的方法是要被子類實現(xiàn)的俺孙,而static與子類扯不上關(guān)系!
????????native方法表示該方法要用另外一種依賴平臺的編程語言實現(xiàn)的掷贾,不存在著被子類實現(xiàn)的問題睛榄,所以,它也不能是抽象的想帅,不能與abstract混用场靴。例如,F(xiàn)ileOutputSteam類要硬件打交道,底層的實現(xiàn)用的是操作系統(tǒng)相關(guān)的api實現(xiàn)旨剥;例如咧欣,在windows用c語言實現(xiàn)的,所以轨帜,查看jdk的源代碼魄咕,可以發(fā)現(xiàn)FileOutputStream的open方法的定義如下:
private native void open(Stringname) throwsFileNotFoundException;
????????如果我們要用java調(diào)用別人寫的c語言函數(shù),我們是無法直接調(diào)用的蚌父,我們需要按照java的要求寫一個c語言的函數(shù)哮兰,又我們的這個c語言函數(shù)去調(diào)用別人的c語言函數(shù)。由于我們的c語言函數(shù)是按java的要求來寫的苟弛,我們這個c語言函數(shù)就可以與java對接上喝滞,java那邊的對接方式就是定義出與我們這個c函數(shù)相對應(yīng)的方法,java中對應(yīng)的方法不需要寫具體的代碼膏秫,但需要在前面聲明native囤躁。
????????關(guān)于synchronized與abstract合用的問題,我覺得也不行荔睹,因為在我?guī)啄甑膶W(xué)習(xí)和開發(fā)中狸演,從來沒見到過這種情況,并且我覺得synchronized應(yīng)該是作用在一個具體的方法上才有意義僻他。而且宵距,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上無法確定this是什么吨拗。
19满哪、內(nèi)部類可以引用它的包含類的成員嗎?有沒有什么限制劝篷?
????????完全可以哨鸭。如果不是靜態(tài)內(nèi)部類,那沒有什么限制娇妓!
????????如果你把靜態(tài)嵌套類當作內(nèi)部類的一種特例像鸡,那在這種情況下不可以訪問外部類的普通成員變量,而只能訪問外部類中的靜態(tài)成員哈恰,例如只估,下面的代碼:
class Outer
{
static int x;
static class Inner
????{
??????? voidtest()
??????? {
??????????????syso(x);
??????? }
????}
}
20、String s = "Hello";s = s + "world!";這兩行代碼執(zhí)行后着绷,原始的String對象中的內(nèi)容到底變了沒有蛔钙?
????????沒有。因為String被設(shè)計成不可變(immutable)類荠医,所以它的所有對象都是不可變對象吁脱。在這段代碼中桑涎,s原先指向一個String對象,內(nèi)容是 "Hello"兼贡,然后我們對s進行了+操作石洗,那么s所指向的那個對象是否發(fā)生了改變呢?答案是沒有紧显。這時讲衫,s不指向原來那個對象了,而指向了另一個 String對象孵班,內(nèi)容為"Hello world!"涉兽,原來那個對象還存在于內(nèi)存之中,只是s這個引用變量不再指向它了篙程。
通過上面的說明枷畏,我們很容易導(dǎo)出另一個結(jié)論,如果經(jīng)常對字符串進行各種各樣的修改虱饿,或者說拥诡,不可預(yù)見的修改,那么使用String來代表字符串的話會引起很大的內(nèi)存開銷氮发。因為String對象建立之后不能再改變渴肉,所以對于每一個不同的字符串,都需要一個String對象來表示爽冕。這時仇祭,應(yīng)該考慮使用StringBuffer類,它允許修改颈畸,而不是每個不同的字符串都要生成一個新的對象乌奇。并且,這兩種類的對象轉(zhuǎn)換十分容易眯娱。
同時礁苗,我們還可以知道,如果要使用內(nèi)容相同的字符串徙缴,不必每次都new一個String试伙。例如我們要在構(gòu)造器中對一個名叫s的String引用變量進行初始化,把它設(shè)置為初始值娜搂,應(yīng)當這樣做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
后者每次都會調(diào)用構(gòu)造器迁霎,生成新對象,性能低下且內(nèi)存開銷大百宇,并且沒有意義,因為String對象不可改變秘豹,所以對于內(nèi)容相同的字符串携御,只要一個String對象來表示就可以了。也就說,多次調(diào)用上面的構(gòu)造器創(chuàng)建多個對象啄刹,他們的????????????String類型屬性s都指向同一個對象涮坐。
上面的結(jié)論還基于這樣一個事實:對于字符串常量,如果內(nèi)容相同誓军,Java認為它們代表同一個String對象袱讹。而用關(guān)鍵字new調(diào)用構(gòu)造器,總是會創(chuàng)建一個新的對象昵时,無論內(nèi)容是否相同捷雕。
至于為什么要把String類設(shè)計成不可變類,是它的用途決定的壹甥。其實不只String救巷,很多Java標準類庫中的類都是不可變的。在開發(fā)一個系統(tǒng)的時候句柠,我們有時候也需要設(shè)計不可變類浦译,來傳遞一組相關(guān)的值,這也是面向?qū)ο笏枷氲捏w現(xiàn)溯职。不可變類有一些優(yōu)點精盅,比如因為它的對象是只讀的,所以多線程并發(fā)訪問也不會有任何問題谜酒。當然也有一些缺點渤弛,比如每個不同的狀態(tài)都要一個對象來代表,可能會造成性能上的問題甚带。所以Java標準類庫還提供了一個可變版本她肯,即StringBuffer。
21鹰贵、ArrayList和Vector的區(qū)別
????????這兩個類都實現(xiàn)了List接口(List接口繼承了Collection接口)晴氨,他們都是有序集合,即存儲在這兩個集合中的元素的位置都是有順序的碉输,相當于一種動態(tài)的數(shù)組籽前,我們以后可以按位置索引號取出某個元素,并且其中的數(shù)據(jù)是允許重復(fù)的敷钾,這是與HashSet之類的集合的最大不同處枝哄,HashSet之類的集合不可以按索引號去檢索其中的元素,也不允許有重復(fù)的元素阻荒。
ArrayList與Vector的區(qū)別主要包括兩個方面:.
(1)同步性:
?????? Vector是線程安全的挠锥,也就是說是它的方法之間是線程同步的,而ArrayList是線程序不安全的侨赡,它的方法之間是線程不同步的蓖租。如果只有一個線程會訪問到集合粱侣,那最好是使用ArrayList,因為它不考慮線程安全蓖宦,效率會高些齐婴;如果有多個線程會訪問到集合,那最好是使用Vector稠茂,因為不需要我們自己再去考慮和編寫線程安全的代碼柠偶。
(2)數(shù)據(jù)增長:
?????? ArrayList與Vector都有一個初始的容量大小,當存儲進它們里面的元素的個數(shù)超過了容量時睬关,就需要增加ArrayList與Vector的存儲空間诱担,每次要增加存儲空間時,不是只增加一個存儲單元共螺,而是增加多個存儲單元该肴,每次增加的存儲單元的個數(shù)在內(nèi)存空間利用與程序效率之間要取得一定的平衡。Vector默認增長為原來兩倍藐不,而ArrayList的增長策略在文檔中沒有明確規(guī)定(從源代碼看到的是增長為原來的1.5倍)匀哄。ArrayList與Vector都可以設(shè)置初始的空間大小,Vector還可以設(shè)置增長的空間大小雏蛮,而ArrayList沒有提供設(shè)置增長空間的方法涎嚼。
??? 總結(jié):即Vector增長原來的一倍,ArrayList增加原來的0.5倍挑秉。
22法梯、HashMap和Hashtable的區(qū)別
????????HashMap是Hashtable的輕量級實現(xiàn)(非線程安全的實現(xiàn)),他們都完成了Map接口犀概,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全立哑,在只有一個線程訪問的情況下,效率要高于Hashtable姻灶。
????????HashMap允許將null作為一個entry的key或者value铛绰,而Hashtable不允許。
HashMap把Hashtable的contains方法去掉了产喉,改成containsvalue和containsKey捂掰。因為contains方法容易讓人引起誤解。
????????Hashtable繼承自Dictionary類曾沈,而HashMap是Java1.2引進的Map interface的一個實現(xiàn)这嚣。
????????最大的不同是,Hashtable的方法是Synchronize的塞俱,而HashMap不是姐帚,在多個線程訪問Hashtable時,不需要自己為它的方法實現(xiàn)同步敛腌,而HashMap就必須為之提供同步卧土。
就HashMap與HashTable主要從三方面來說惫皱。
一.歷史原因:Hashtable是基于陳舊的Dictionary類的像樊,HashMap是Java 1.2引進的Map接口的一個實現(xiàn)
二.同步性:Hashtable是線程安全的尤莺,也就是說是同步的,而HashMap是線程序不安全的生棍,不是同步的
三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value
23颤霎、List和 Map區(qū)別?
????????一個是存儲單列數(shù)據(jù)的集合,另一個是存儲鍵和值這樣的雙列數(shù)據(jù)的集合涂滴,List中存儲的數(shù)據(jù)是有順序友酱,并且允許重復(fù);Map中存儲的數(shù)據(jù)是沒有順序的柔纵,其鍵是不能重復(fù)的缔杉,它的值是可以有重復(fù)的。
24搁料、List,Set, Map是否繼承自Collection接口?
?? List或详,Set是,Map不是
25郭计、List霸琴、Map、Set三個接口昭伸,存取元素時梧乘,各有什么特點?
(這樣的題比較考水平庐杨,兩個方面的水平:一是要真正明白這些內(nèi)容选调,二是要有較強的總結(jié)和表述能力。)
????????首先灵份,List與Set具有相似性仁堪,它們都是單列元素的集合,所以各吨,它們有一個共同的父接口枝笨,叫Collection。Set里面不允許有重復(fù)的元素揭蜒,即不能有兩個相等(注意横浑,不是僅僅是相同)的對象,即假設(shè)Set集合中有了一個A對象屉更,現(xiàn)在我要向Set集合再存入一個B對象徙融,但B對象與A對象equals相等,則B對象存儲不進去瑰谜,所以欺冀,Set集合的add方法有一個boolean的返回值树绩,當集合中沒有某個元素,此時add方法可成功加入該元素時隐轩,則返回true饺饭,當集合含有與某個元素equals相等的元素時,此時add方法無法加入該元素职车,返回結(jié)果為false瘫俊。Set取元素時,不能細說要取第幾個悴灵,只能以Iterator接口取得所有的元素扛芽,再逐一遍歷各個元素。
?????? List表示有先后順序的集合积瞒,注意川尖,不是那種按年齡、按大小茫孔、按價格之類的排序叮喳。當我們多次調(diào)用add(Obje)方法時,每次加入的對象就像火車站買票有排隊順序一樣银酬,按先來后到的順序排序嘲更。有時候,也可以插隊揩瞪,即調(diào)用add(intindex,Obj e)方法赋朦,就可以指定當前對象在集合中的存放位置。一個對象可以被反復(fù)存儲進List中李破,每調(diào)用一次add方法宠哄,這個對象就被插入進集合中一次,其實嗤攻,并不是把這個對象本身存儲進了集合中毛嫉,而是在集合中用一個索引變量指向這個對象,當這個對象被add多次時妇菱,即相當于集合中有多個索引指向了這個對象承粤,如圖x所示。List除了可以用Iterator接口取得所有的元素闯团,再逐一遍歷各個元素之外辛臊,還可以調(diào)用get(index i)來明確說明取第幾個。
?????? Map與List和Set不同房交,它是雙列的集合彻舰,其中有put方法,定義如下:put(obj key,obj value),每次存儲時刃唤,要存儲一對key/value隔心,不能存儲重復(fù)的key,這個重復(fù)的規(guī)則也是按equals比較相等尚胞。取則可以根據(jù)key獲得相應(yīng)的value硬霍,即get(Object key)返回值為key所對應(yīng)的value。另外辐真,也可以獲得所有的key的結(jié)合须尚,還可以獲得所有的value的結(jié)合崖堤,還可以獲得key和value組合成的Map.Entry對象的集合侍咱。
?List以特定次序來持有元素,可有重復(fù)元素密幔。Set無法擁有重復(fù)元素,內(nèi)部排序楔脯。Map保存key-value值,value可多值胯甩。
26昧廷、說出ArrayList,Vector,LinkedList的存儲性能和特性
????????ArrayList和Vector都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素數(shù)大于實際存儲的數(shù)據(jù)以便增加和插入元素偎箫,它們都允許直接按序號索引元素木柬,但是插入元素要涉及數(shù)組元素移動等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢淹办,Vector由于使用了synchronized方法(線程安全)眉枕,通常性能上較ArrayList差。而LinkedList使用雙向鏈表實現(xiàn)存儲怜森,按序號索引數(shù)據(jù)需要進行前向或后向遍歷速挑,索引就變慢了,但是插入數(shù)據(jù)時只需要記錄本項的前后項即可副硅,所以插入速度較快姥宝。
????????LinkedList也是線程不安全的,LinkedList提供了一些方法恐疲,使得LinkedList可以被當作堆棧和隊列來使用腊满。
27、去掉一個Vector集合中重復(fù)的元素
Vector newVector = new Vector();
For (int i=0;i<vector.size();i++)
{
Object obj = vector.get(i);
?????? if(!newVector.contains(obj);
?????????????newVector.add(obj);
}
還有一種簡單的方式培己,利用了Set不允許重復(fù)元素:
HashSetset = new HashSet(vector);
28碳蛋、Collection和Collections的區(qū)別。
????????Collection是集合類的上級接口漱凝,繼承他的接口主要有Set和List.
????????Collections是針對集合類的一個幫助類疮蹦,他提供一系列靜態(tài)方法實現(xiàn)對各種集合的搜索、排序茸炒、線程安全化等操作愕乎。
29阵苇、Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢?是用==還是equals()?它們有何區(qū)別?
????????Set里的元素是不能重復(fù)的感论,元素重復(fù)與否是使用equals()方法進行判斷的绅项。
?? ???? ==和equal區(qū)別也是考爛了的題,這里說一下:
????????==操作符專門用來比較兩個變量的值是否相等比肄,也就是用于比較變量所對應(yīng)的內(nèi)存中所存儲的數(shù)值是否相同快耿,要比較兩個基本類型的數(shù)據(jù)或兩個引用變量是否相等,只能用==操作符芳绩。
equals方法是用于比較兩個獨立對象的內(nèi)容是否相同掀亥,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的妥色。?
????????比如:兩條new語句創(chuàng)建了兩個對象搪花,然后用a/b這兩個變量分別指向了其中一個對象,這是兩個不同的對象嘹害,它們的首地址是不同的撮竿,即a和b中存儲的數(shù)值是不相同的,所以笔呀,表達式a==b將返回false幢踏,而這兩個對象中的內(nèi)容是相同的,所以许师,表達式a.equals(b)將返回true房蝉。
30、你所知道的集合類都有哪些枯跑?主要方法惨驶?
????????最常用的集合類是 List 和 Map。 List的具體實現(xiàn)包括 ArrayList和 Vector敛助,它們是可變大小的列表粗卜,比較適合構(gòu)建、存儲和操作任何類型對象的元素列表纳击。 List適用于按數(shù)值索引訪問元素的情形续扔。
????????Map 提供了一個更通用的元素存儲方法。 Map集合類用于存儲元素對(稱作"鍵"和"值")焕数,其中每個鍵映射到一個值纱昧。
????????它們都有增刪改查的方法。
????????對于set堡赔,大概的方法是add,remove, contains等
????????對于map识脆,大概的方法就是put,remove,contains等
????????List類會有g(shù)et(int index)這樣的方法,因為它可以按順序取元素灼捂,而set類中沒有g(shù)et(int index)這樣的方法离例。List和set都可以迭代出所有元素,迭代時先要得到一個iterator對象悉稠,所以宫蛆,set和list類都有一個iterator方法,用于返回那個iterator對象的猛。map可以返回三個集合耀盗,一個是返回所有的key的集合,另外一個返回的是所有value的集合卦尊,再一個返回的key和value組合成的EntrySet對象的集合叛拷,map也有g(shù)et方法,參數(shù)是key猫牡,返回值是key對應(yīng)的value胡诗,這個自由發(fā)揮,也不是考記方法的能力淌友,這些編程過程中會有提示,結(jié)合他們?nèi)叩牟煌f一下用法就行骇陈。
31震庭、String s = new String("xyz");創(chuàng)建了幾個StringObject?是否可以繼承String類?
兩個或一個都有可能你雌,”xyz”對應(yīng)一個對象器联,這個對象放在字符串常量緩沖區(qū),常量”xyz”不管出現(xiàn)多少遍婿崭,都是緩沖區(qū)中的那一個拨拓。NewString每寫一遍,就創(chuàng)建一個新的對象氓栈,它使用常量”xyz”對象的內(nèi)容來創(chuàng)建出一個新String對象渣磷。如果以前就用過’xyz’,那么這里就不會創(chuàng)建”xyz”了授瘦,直接從緩沖區(qū)拿醋界,這時創(chuàng)建了一個StringObject;但如果以前沒有用過"xyz"提完,那么此時就會創(chuàng)建一個對象并放入緩沖區(qū)形纺,這種情況它創(chuàng)建兩個對象。至于String類是否繼承徒欣,答案是否定的逐样,因為String默認final修飾,是不可繼承的。
32脂新、String和StringBuffer的區(qū)別
????????JAVA平臺提供了兩個類:String和StringBuffer秽澳,它們可以儲存和操作字符串,即包含多個字符的字符數(shù)據(jù)戏羽。這個String類提供了數(shù)值不可改變的字符串担神。而這個StringBuffer類提供的字符串可以進行修改。當你知道字符數(shù)據(jù)要改變的時候你就可以使用StringBuffer始花。典型地妄讯,你可以使用StringBuffers來動態(tài)構(gòu)造字符數(shù)據(jù)。
33酷宵、下面這條語句一共創(chuàng)建了多少個對象:String s="a"+"b"+"c"+"d";
對于如下代碼:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一條語句打印的結(jié)果為false亥贸,第二條語句打印的結(jié)果為true,這說明javac編譯可以對字符串常量直接相加的表達式進行優(yōu)化浇垦,不必要等到運行期再去進行加法運算處理炕置,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結(jié)果男韧。
題目中的第一行代碼被編譯器在編譯時優(yōu)化后朴摊,相當于直接定義了一個”abcd”的字符串萌抵,所以溪胶,上面的代碼應(yīng)該只創(chuàng)建了一個String對象。寫如下兩行代碼曲楚,
??????????String s ="a" + "b" +"c" + "d";
??????????System.out.println(s== "abcd");
最終打印的結(jié)果應(yīng)該為true朦前。
34介杆、try {}里有一個return語句,那么緊跟在這個try后的finally{}里的code會不會被執(zhí)行韭寸,什么時候被執(zhí)行春哨,在return前還是后?
??????? 我們知道finally{}中的語句是一定會執(zhí)行的,那么這個可能正常脫口而出就是return之前恩伺,return之后可能就出了這個方法了赴背,鬼知道跑哪里去了,但更準確的應(yīng)該是在return中間執(zhí)行莫其,請看下面程序代碼的運行結(jié)果:
public classTest {
??? public static void main(String[]args) {
?????? System.out.println(newTest().test());;
??? }
??? static int test()
??? {
?????? intx = 1;
?????? try
?????? {
??????????returnx;
?????? }
?????? finally
?????? {
??????????++x;
?????? }
??? }
??
}
---------執(zhí)行結(jié)果 ---------
1
運行結(jié)果是1癞尚,為什么呢?主函數(shù)調(diào)用子函數(shù)并得到結(jié)果的過程乱陡,好比主函數(shù)準備一個空罐子浇揩,當子函數(shù)要返回結(jié)果時,先把結(jié)果放在罐子里憨颠,然后再將程序邏輯返回到主函數(shù)胳徽。所謂返回积锅,就是子函數(shù)說,我不運行了养盗,你主函數(shù)繼續(xù)運行吧缚陷,這沒什么結(jié)果可言,結(jié)果是在說這話之前放進罐子里的往核。
35箫爷、final, finally, finalize的區(qū)別。?
????????final 用于聲明屬性聂儒,方法和類虎锚,分別表示屬性不可變,方法不可覆蓋衩婚,類不可繼承窜护。內(nèi)部類要訪問局部變量,局部變量必須定義成final類型非春。
????????finally是異常處理語句結(jié)構(gòu)的一部分柱徙,表示總是執(zhí)行。
finalize是Object類的一個方法奇昙,在垃圾收集器執(zhí)行的時候會調(diào)用被回收對象的此方法护侮,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關(guān)閉文件等敬矩。但是JVM不保證此方法總被調(diào)用
36概行、運行時異常與一般異常有何異同?
????????異常表示程序運行過程中可能出現(xiàn)的非正常狀態(tài)弧岳,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤业踏。java編譯器要求方法必須聲明拋出可能發(fā)生的非運行時異常禽炬,但是并不要求必須聲明拋出未被捕獲的運行時異常。
37勤家、error和exception有什么區(qū)別?
????????error 表示恢復(fù)不是不可能但很困難的情況下的一種嚴重問題腹尖。比如說內(nèi)存溢出。不可能指望程序能處理這樣的情況伐脖。exception表示一種設(shè)計或?qū)崿F(xiàn)問題热幔。也就是說,它表示如果程序運行正常讼庇,從不會發(fā)生的情況绎巨。
38、簡單說說Java中的異常處理機制的簡單原理和應(yīng)用蠕啄。
????????異常是指java程序運行時(非編譯)所發(fā)生的非正常情況或錯誤场勤,與現(xiàn)實生活中的事件很相似戈锻,現(xiàn)實生活中的事件可以包含事件發(fā)生的時間、地點和媳、人物格遭、情節(jié)等信息,可以用一個對象來表示留瞳,Java使用面向?qū)ο蟮姆绞絹硖幚懋惓>苎福殉绦蛑邪l(fā)生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的信息她倘。
????????Java對異常進行了分類璧微,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable帝牡,Throwable下面又派生了兩個子類:
Error和Exception往毡,Error表示應(yīng)用程序本身無法克服和恢復(fù)的一種嚴重問題,程序只有奔潰了靶溜,例如开瞭,說內(nèi)存溢出和線程死鎖等系統(tǒng)問題。
????????Exception表示程序還能夠克服和恢復(fù)的問題罩息,其中又分為系統(tǒng)異常和普通異常:
????????系統(tǒng)異常是軟件本身缺陷所導(dǎo)致的問題嗤详,也就是軟件開發(fā)人員考慮不周所導(dǎo)致的問題,軟件使用者無法克服和恢復(fù)這種問題瓷炮,但在這種問題下還可以讓軟件系統(tǒng)繼續(xù)運行或者讓軟件掛掉葱色,例如,數(shù)組腳本越界(ArrayIndexOutOfBoundsException)娘香,空指針異常(NullPointerException)苍狰、類轉(zhuǎn)換異常(ClassCastException);
????????普通異常是運行環(huán)境的變化或異常所導(dǎo)致的問題烘绽,是用戶能夠克服的問題淋昭,例如,網(wǎng)絡(luò)斷線安接,硬盤空間不夠翔忽,發(fā)生這樣的異常后,程序不應(yīng)該死掉盏檐。
java為系統(tǒng)異常和普通異常提供了不同的解決方案歇式,編譯器強制普通異常必須try..catch處理或用throws聲明繼續(xù)拋給上層調(diào)用方法處理,所以普通異常也稱為checked異常胡野,而系統(tǒng)異巢氖В可以處理也可以不處理,所以给涕,編譯器不強制用try..catch處理或用throws聲明豺憔,所以系統(tǒng)異常也稱為unchecked異常额获。
39、Java 中堆和棧有什么區(qū)別恭应?
JVM 中堆和棧屬于不同的內(nèi)存區(qū)域抄邀,使用目的也不同。棧常用于保存方法幀和局部變量昼榛,而對象總是在堆上分配境肾。棧通常都比堆小,也不會在多個線程之間共享胆屿,而堆被整個 JVM 的所有線程共享奥喻。
????????棧:在函數(shù)中定義的一些基本類型的變量和對象的引用變量都是在函數(shù)的棧內(nèi)存中分配,當在一段代碼塊定義一個變量時非迹,Java 就在棧中為這個變量分配內(nèi)存空間环鲤,當超過變量的作用域后,Java 會自動釋放掉為該變量分配的內(nèi)存空間憎兽,該內(nèi)存空間可以立即被另作它用冷离。
????????堆:堆內(nèi)存用來存放由 new 創(chuàng)建的對象和數(shù)組,在堆中分配的內(nèi)存纯命,由 Java 虛擬機的自動垃圾回收器來管理西剥。在堆中產(chǎn)生了一個數(shù)組或者對象之后,還可以在棧中定義一個特殊的變量亿汞,讓棧中的這個變量的取值等于數(shù)組或?qū)ο笤诙褍?nèi)存中的首地址瞭空,棧中的這個變量就成了數(shù)組或?qū)ο蟮囊米兞浚院缶涂梢栽诔绦蛑惺褂脳V械囊米兞縼碓L問堆中的數(shù)組或者對象疗我,引用變量就相當于是為數(shù)組或者對象起的一個名稱咆畏。
40、能將 int 強制轉(zhuǎn)換為 byte 類型的變量嗎吴裤?如果該值大于 byte 類型的范圍鳖眼,將會出現(xiàn)什么現(xiàn)象??
我們可以做強制轉(zhuǎn)換嚼摩,但是 Java 中 int 是 32 位的,而 byte 是 8 位的矿瘦,所以枕面,如果強制轉(zhuǎn)化,int 類型的高 24 位將會被丟棄缚去,因為byte 類型的范圍是從 -128 到 128潮秘。
41、a.hashCode() 有什么用易结?與 a.equals(b) 有什么關(guān)系枕荞?
hashCode() 方法對應(yīng)對象整型的 hash 值柜候。它常用于基于 hash 的集合類,如 Hashtable躏精、HashMap渣刷、LinkedHashMap等等。它與 equals() 方法關(guān)系特別緊密矗烛。根據(jù) Java 規(guī)范辅柴,兩個使用 equal() 方法來判斷相等的對象,必須具有相同的 hash code瞭吃。
42碌嘀、字節(jié)流與字符流的區(qū)別
?????? 要把一段二進制數(shù)據(jù)數(shù)據(jù)逐一輸出到某個設(shè)備中,或者從某個設(shè)備中逐一讀取一段二進制數(shù)據(jù)歪架,不管輸入輸出設(shè)備是什么股冗,我們要用統(tǒng)一的方式來完成這些操作,用一種抽象的方式進行描述和蚪,這個抽象描述方式起名為IO流止状,對應(yīng)的抽象類為OutputStream和InputStream,不同的實現(xiàn)類就代表不同的輸入和輸出設(shè)備惠呼,它們都是針對字節(jié)進行操作的导俘。
?????? 計算機中的一切最終都是二進制的字節(jié)形式存在。對于經(jīng)常用到的中文字符剔蹋,首先要得到其對應(yīng)的字節(jié)旅薄,然后將字節(jié)寫入到輸出流。讀取時泣崩,首先讀到的是字節(jié)少梁,可是我們要把它顯示為字符,我們需要將字節(jié)轉(zhuǎn)換成字符矫付。由于這樣的需求很廣泛凯沪,Java專門提供了字符流包裝類。
? ????底層設(shè)備永遠只接受字節(jié)數(shù)據(jù)买优,有時候要寫字符串到底層設(shè)備妨马,需要將字符串轉(zhuǎn)成字節(jié)再進行寫入。字符流是字節(jié)流的包裝杀赢,字符流則是直接接受字符串烘跺,它內(nèi)部將串轉(zhuǎn)成字節(jié),再寫入底層設(shè)備脂崔,這為我們向IO設(shè)備寫入或讀取字符串提供了一點點方便滤淳。
? ????字符向字節(jié)轉(zhuǎn)換時,要注意編碼的問題砌左,因為字符串轉(zhuǎn)成字節(jié)數(shù)組脖咐,其實是轉(zhuǎn)成該字符的某種編碼的字節(jié)形式铺敌,讀取也是反之的道理。
43屁擅、什么是java序列化偿凭,如何實現(xiàn)java序列化?或者請解釋Serializable接口的作用煤蹭。
????????我們有時候?qū)⒁粋€java對象變成字節(jié)流的形式傳出去或者從一個字節(jié)流中恢復(fù)成一個java對象笔喉,例如,要將java對象存儲到硬盤或者傳送給網(wǎng)絡(luò)上的其他計算機硝皂,這個過程我們可以自己寫代碼去把一個java對象變成某個格式的字節(jié)流再傳輸常挚。
????????但是,jre本身就提供了這種支持稽物,我們可以調(diào)用OutputStream的writeObject方法來做奄毡,如果要讓java幫我們做,要被傳輸?shù)膶ο蟊仨殞崿F(xiàn)serializable接口贝或,這樣吼过,javac編譯時就會進行特殊處理,編譯的類才可以被writeObject方法操作咪奖,這就是所謂的序列化盗忱。需要被序列化的類必須實現(xiàn)Serializable接口,該接口是一個mini接口羊赵,其中沒有需要實現(xiàn)方法趟佃,implements Serializable只是為了標注該對象是可被序列化的。
????????例如昧捷,在web開發(fā)中闲昭,如果對象被保存在了Session中,tomcat在重啟時要把Session對象序列化到硬盤靡挥,這個對象就必須實現(xiàn)Serializable接口序矩。如果對象要經(jīng)過分布式系統(tǒng)進行網(wǎng)絡(luò)傳輸,被傳輸?shù)膶ο缶捅仨殞崿F(xiàn)Serializable接口跋破。
44簸淀、描述一下JVM加載class文件的原理機制?
????????JVM中類的裝載是由ClassLoader和它的子類來實現(xiàn)的,Java ClassLoader是一個重要的Java運行時系統(tǒng)組件。它負責(zé)在運行時查找和裝入類文件的類毒返。
45啃擦、heap和stack有什么區(qū)別。
????????java的內(nèi)存分為兩類饿悬,一類是棧內(nèi)存,一類是堆內(nèi)存聚霜。棧內(nèi)存是指程序進入一個方法時狡恬,會為這個方法單獨分配一塊私屬存儲空間珠叔,用于存儲這個方法內(nèi)部的局部變量,當這個方法結(jié)束時弟劲,分配給這個方法的棧會釋放祷安,這個棧中的變量也將隨之釋放。
????????堆是與棧作用不同的內(nèi)存兔乞,一般用于存放不在當前方法棧中的那些數(shù)據(jù)汇鞭,例如,使用new創(chuàng)建的對象都放在堆里庸追,所以霍骄,它不會隨方法的結(jié)束而消失。方法中的局部變量使用final修飾后淡溯,放在堆中读整,而不是棧中。
46咱娶、GC是什么?為什么要有GC?
????????GC是垃圾收集的意思(Gabage Collection),內(nèi)存處理是編程人員容易出現(xiàn)問題的地方米间,忘記或者錯誤的內(nèi)存回收會導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java提供的GC功能可以自動監(jiān)測對象是否超過作用域從而達到自動回收內(nèi)存的目的膘侮,Java語言沒有提供釋放已分配內(nèi)存的顯示操作方法屈糊。
47、垃圾回收的優(yōu)點和原理琼了。并考慮2種回收機制逻锐。
????????Java語言中一個顯著的特點就是引入了垃圾回收機制,使c++程序員最頭疼的內(nèi)存管理的問題迎刃而解表伦,它使得Java程序員在編寫程序的時候不再需要考慮內(nèi)存管理谦去。由于垃圾回收機制,Java中的對象不再有"作用域"的概念蹦哼,只有對象的引用才有"作用域"鳄哭。
????????垃圾回收可以有效的防止內(nèi)存泄露,有效的使用可以使用的內(nèi)存纲熏。垃圾回收器通常是作為一個單獨的低級別的線程運行妆丘,不可預(yù)知的情況下對內(nèi)存堆中已經(jīng)死亡的或者長時間沒有使用的對象進行清除和回收,程序員不能實時的調(diào)用垃圾回收器對某個對象或所有對象進行垃圾回收局劲。
????????回收機制有分代復(fù)制垃圾回收和標記垃圾回收勺拣,增量垃圾回收。
48鱼填、垃圾回收器的基本原理是什么药有?垃圾回收器可以馬上回收內(nèi)存嗎?有什么辦法主動通知虛擬機進行垃圾回收?
????????對于GC來說愤惰,當程序員創(chuàng)建對象時苇经,GC就開始監(jiān)控這個對象的地址、大小以及使用情況宦言。通常扇单,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的"奠旺,哪些對象是"不可達的"蜘澜。當GC確定一些對象為"不可達"時,GC就有責(zé)任回收這些內(nèi)存空間响疚。
????????程序員可以手動執(zhí)行System.gc()鄙信,通知GC運行,但是Java語言規(guī)范并不保證GC一定會執(zhí)行稽寒。
49扮碧、Java 中,throw 和 throws 有什么區(qū)別
throw 用于拋出 java.lang.Throwable 類的一個實例化對象杏糙,意思是說你可以通過關(guān)鍵字 throw 拋出一個Exception慎王,如:?
throw new IllegalArgumentException(“XXXXXXXXX″)
????????而throws 的作用是作為方法聲明和簽名的一部分,方法被拋出相應(yīng)的異常以便調(diào)用者能處理宏侍。Java 中赖淤,任何未處理的受檢查異常強制在 throws 子句中聲明。
50谅河,java中會存在內(nèi)存泄漏嗎咱旱,請簡單描述。
????????先解釋什么是內(nèi)存泄漏:所謂內(nèi)存泄露就是指一個不再被程序使用的對象或變量一直被占據(jù)在內(nèi)存中绷耍。java中有垃圾回收機制吐限,它可以保證當對象不再被引用的時候,對象將自動被垃圾回收器從內(nèi)存中清除掉褂始。
由于Java使用有向圖的方式進行垃圾回收管理诸典,可以消除引用循環(huán)的問題,例如有兩個對象崎苗,相互引用狐粱,只要它們和根進程不可達,那么GC也是可以回收它們的胆数。
java中的內(nèi)存泄露的情況:長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內(nèi)存泄露肌蜻,盡管短生命周期對象已經(jīng)不再需要,但是因為長生命周期對象持有它的引用而導(dǎo)致不能被回收必尼,這就是java中內(nèi)存泄露的發(fā)生場景蒋搜,通俗地說,就是程序員可能創(chuàng)建了一個對象,以后一直不再使用這個對象齿诞,這個對象卻一直被引用酸休,即這個對象無用但是卻無法被垃圾回收器回收的,這就是java中可能出現(xiàn)內(nèi)存泄露的情況祷杈,例如,緩存系統(tǒng)渗饮,我們加載了一個對象放在緩存中(例如放在一個全局map對象中)但汞,然后一直不再使用它,這個對象一直被緩存引用互站,但卻不再被使用私蕾。