java高頻率基礎(chǔ)面試題
一孕荠、是否可以從一個static方法內(nèi)部發(fā)出對非static方法的調(diào)用皇忿?
(視頻教程推薦:java課程)
不可以翘魄。因為非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)用。
二嗽测、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ù)的最大值和最小值的常量皆刺。
三少辣、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懈玻。
這里有一些筆誤巧婶,floor的英文意義是地板乾颁,該方法就表示向下取整,Math.floor(11.6)的結(jié)果為11,Math.floor(-11.6)的結(jié)果是-12艺栈;
(更多相關(guān)面試題推薦:java面試題及答案)
四英岭、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躏尉,那么就不能在子類對其進行重載,如果定義的話后众,也只是定義了一個新方法胀糜,而不會達到重載的效果颅拦。
五、接口是否可繼承接口?抽象類是否可實現(xiàn)(implements)接口?抽象類是否可繼承具體類(concreteclass)?抽象類中是否可以有靜態(tài)的main方法教藻?
接口可以繼承接口距帅。抽象類可以實現(xiàn)(implements)接口,抽象類可以繼承具體類括堤。抽象類中可以有靜態(tài)的main方法碌秸。
備注:只要明白了接口和抽象類的本質(zhì)和作用,這些問題都很好回答悄窃,你想想讥电,如果你是java語言的設(shè)計者,你是否會提供這樣的支持轧抗,如果不提供的話恩敌,有什么理由嗎?如果你沒有道理不提供横媚,那答案就是肯定的了潮剪。
只要記住抽象類與普通類的唯一區(qū)別就是不能創(chuàng)建實例對象和允許有abstract方法。
六分唾、Java中實現(xiàn)多態(tài)的機制是什么抗碰?
靠的是父類或接口定義的引用變量可以指向子類或具體實現(xiàn)類的實例對象,而程序調(diào)用的方法在運行期才動態(tài)綁定绽乔,就是引用變量所指向的具體實例對象的方法弧蝇,也就是內(nèi)存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法折砸。
七看疗、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)多個接口愁茁,但只能繼承一個抽象類蚕钦。
(相關(guān)教程推薦:java入門教程)
八、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是什么。
九瀑志、內(nèi)部類可以引用它的包含類的成員嗎涩搓?有沒有什么限制?
完全可以劈猪。如果不是靜態(tài)內(nèi)部類昧甘,那沒有什么限制!
如果你把靜態(tài)嵌套類當作內(nèi)部類的一種特例战得,那在這種情況下不可以訪問外部類的普通成員變量充边,而只能訪問外部類中的靜態(tài)成員,例如常侦,下面的代碼:
class Outer
{
static int x;
static class Inner
????{
????????voidtest()
????????{
??????????????syso(x);
????????}
????}
}
十浇冰、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";
}
...
}
而非
1
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攻走。