Java面試題-基礎篇二(乾貨)

十一、是否能夠從一個static方法內部發出對非static方法的調用?java

        不能夠。由於非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠直接調用。也就是說,當一個static方法被調用時,可能尚未建立任何實例對象,若是從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪一個對象上的呢?這個邏輯沒法成立,因此,一個static方法內部發出對非static方法的調用。web

 

十二、Integer與int的區別算法

        int是java提供的8種原始數據類型之一。Java爲每一個原始類型提供了封裝類,Integer是java爲int提供的封裝類。int的默認值爲0,而Integer的默認值爲null,即Integer能夠區分出未賦值和值爲0的區別,int則沒法表達出未賦值的狀況。編程

        例如:要想表達出沒有參加考試和考試成績爲0的區別,則只能使用Integer。在JSP開發中,Integer的默認爲null,因此用el表達式在文本框中顯示時,值爲空白字符串,而int默認的默認值爲0,因此用el表達式在文本框中顯示時,結果爲0,因此,int不適合做爲web層的表單數據的類型。windows

        在Hibernate中,若是將OID定義爲Integer類型,那麼Hibernate就能夠根據其值是否爲null而判斷一個對象是不是臨時的,若是將OID定義爲了int類型,還須要在hbm映射文件中設置其unsaved-value屬性爲0。api

        另外,Integer提供了多個與整數相關的操做方法,例如,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。多線程

 

1三、Math.round(11.5)等於多少?Math.round(-11.5)等於多少?併發

        Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的做用與它們的英文名稱的含義相對應。eclipse

        例如,ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果爲12,Math.ceil(-11.3)的結果是-11;floor的英文意義是地板,該方法就表示向下取整,Math.ceil(11.6)的結果爲11,Math.ceil(-11.6)的結果是-12;最難掌握的是round方法,它表示「四捨五入」,算法爲Math.floor(x+0.5),即將原來的數字加上0.5後再向下取整,因此,Math.round(11.5)的結果爲12,Math.round(-11.5)的結果爲-11。編程語言

這裏有一些筆誤,floor的英文意義是地板,該方法就表示向下取整,Math.floor(11.6)的結果爲11,Math.floor(-11.6)的結果是-12;

 

1四、Overload和Override的區別?Overloaded的方法是否能夠改變返回值的類型?

        Overload是重載的意思,Override是覆蓋的意思,也就是重寫。

        重載Overload表示同一個類中能夠有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不一樣)。

        重寫Override表示子類中的方法能夠與父類中的某個方法的名稱和參數徹底相同,經過子類建立的實例對象調用這個方法時,將調用子類中的定義方法,這至關於把父類中定義的那個徹底相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,由於子類能夠解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的更大,不能更小。若是父類的方法是private類型,那麼,子類則不存在覆蓋的限制,至關於子類中增長了一個全新的方法。

        至於Overloaded的方法是否能夠改變返回值的類型這個問題,要看你倒底想問什麼呢?這個題目很模糊。若是幾個Overloaded的方法的參數列表不同,它們的返回者類型固然也能夠不同。但我估計你想問的問題是:若是兩個方法的參數列表徹底同樣,是否可讓它們的返回值不一樣來實現重載Overload。這是不行的,咱們能夠用反證法來講明這個問題,由於咱們有時候調用一個方法時也能夠不定義返回結果變量,即不要關心其返回結果,例如,咱們調用map.remove(key)方法時,雖然remove方法有返回值,可是咱們一般都不會定義接收返回結果的變量,這時候假設該類中有兩個名稱和參數列表徹底相同的方法,僅僅是返回類型不一樣,java就沒法肯定編程者倒底是想調用哪一個方法了,由於它沒法經過返回結果類型來判斷。

        override能夠翻譯爲覆蓋,從字面就能夠知道,它是覆蓋了一個方法而且對其重寫,以求達到不一樣的做用。對咱們來講最熟悉的覆蓋就是對接口方法的實現,在接口中通常只是對方法進行了聲明,而咱們在實現時,就須要實現接口聲明的全部方法。除了這個典型的用法之外,咱們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意如下的幾點:

        一、覆蓋的方法的標誌必需要和被覆蓋的方法的標誌徹底匹配,才能達到覆蓋的效果;

        二、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;

        三、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;

        四、被覆蓋的方法不能爲private,不然在其子類中只是新定義了一個方法,並無對其進行覆蓋。

        Overload對咱們來講可能比較熟悉,能夠翻譯爲重載,它是指咱們能夠定義一些名稱相同的方法,經過定義不一樣的輸入參數來區分這些方法,而後再調用時,VM就會根據不一樣的參數樣式,來選擇合適的方法執行。在使用重載要注意如下的幾點:

        一、在使用重載時只能經過不一樣的參數樣式。例如,不一樣的參數類型,不一樣的參數個數,不一樣的參數順序(固然,同一方法內的幾個參數類型必須不同,例如能夠是fun(int,float),可是不能爲fun(int,int));

        二、不能經過訪問權限、返回類型、拋出的異常進行重載;

        三、方法的異常類型和數目不會對重載形成影響;

        四、對於繼承來講,若是某一方法在父類中是訪問權限是priavte,那麼就不能在子類對其進行重載,若是定義的話,也只是定義了一個新方法,而不會達到重載的效果。

 

1五、接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concreteclass)?抽象類中是否能夠有靜態的main方法?

        接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類能夠繼承具體類。抽象類中能夠有靜態的main方法。

        備註:只要明白了接口和抽象類的本質和做用,這些問題都很好回答,你想一想,若是你是java語言的設計者,你是否會提供這樣的支持,若是不提供的話,有什麼理由嗎?若是你沒有道理不提供,那答案就是確定的了。

        只要記住抽象類與普通類的惟一區別就是不能建立實例對象和容許有abstract方法。

 

1六、Java中實現多態的機制是什麼?

        靠的是父類或接口定義的引用變量能夠指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。

 

1七、abstractclass和interface語法上有什麼區別?

 

1.抽象類能夠有構造方法,接口中不能有構造方法。

2.抽象類中能夠有普通成員變量,接口中沒有普通成員變量

3.抽象類中能夠包含非抽象的普通方法,接口中的全部方法必須都是抽象的,不能有非抽象的普通方法。

4. 抽象類中的抽象方法的訪問類型能夠是public,protected和(默認類型,雖然

eclipse下不報錯,但應該也不行),但接口中的抽象方法只能是public類型的,而且默認即爲public abstract類型。

5. 抽象類中能夠包含靜態方法,接口中不能包含靜態方法

6. 抽象類和接口中均可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型能夠任意,但接口中定義的變量只能是publicstatic final類型,而且默認即爲publicstatic final類型。

7. 一個類能夠實現多個接口,但只能繼承一個抽象類。

 

1八、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?

        abstract的method不能夠是static的,由於抽象的方法是要被子類實現的,而static與子類扯不上關係!

        native方法表示該方法要用另一種依賴平臺的編程語言實現的,不存在着被子類實現的問題,因此,它也不能是抽象的,不能與abstract混用。例如,FileOutputSteam類要硬件打交道,底層的實現用的是操做系統相關的api實現;例如,在windows用c語言實現的,因此,查看jdk的源代碼,能夠發現FileOutputStream的open方法的定義以下:

private native void open(Stringname) throwsFileNotFoundException;

        若是咱們要用java調用別人寫的c語言函數,咱們是沒法直接調用的,咱們須要按照java的要求寫一個c語言的函數,又咱們的這個c語言函數去調用別人的c語言函數。因爲咱們的c語言函數是按java的要求來寫的,咱們這個c語言函數就能夠與java對接上,java那邊的對接方式就是定義出與咱們這個c函數相對應的方法,java中對應的方法不須要寫具體的代碼,但須要在前面聲明native。

        關於synchronized與abstract合用的問題,我以爲也不行,由於在我幾年的學習和開發中,歷來沒見到過這種狀況,而且我以爲synchronized應該是做用在一個具體的方法上纔有意義。並且,方法上的synchronized同步所使用的同步鎖對象是this,而抽象方法上沒法肯定this是什麼。

 

1九、內部類能夠引用它的包含類的成員嗎?有沒有什麼限制?

        徹底能夠。若是不是靜態內部類,那沒有什麼限制!

        若是你把靜態嵌套類看成內部類的一種特例,那在這種狀況下不能夠訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員,例如,下面的代碼:

class Outer

{

static int x;

static class Inner

    {

        voidtest()

        {

              syso(x);

        }

    }

}

 

20、String s = "Hello";s = s + "world!";這兩行代碼執行後,原始的String對象中的內容到底變了沒有?

        沒有。由於String被設計成不可變(immutable)類,因此它的全部對象都是不可變對象。在這段代碼中,s原先指向一個String對象,內容是 "Hello",而後咱們對s進行了+操做,那麼s所指向的那個對象是否發生了改變呢?答案是沒有。這時,s不指向原來那個對象了,而指向了另外一個 String對象,內容爲"Hello world!",原來那個對象還存在於內存之中,只是s這個引用變量再也不指向它了。

        經過上面的說明,咱們很容易導出另外一個結論,若是常常對字符串進行各類各樣的修改,或者說,不可預見的修改,那麼使用String來表明字符串的話會引發很大的內存開銷。由於String對象創建以後不能再改變,因此對於每個不一樣的字符串,都須要一個String對象來表示。這時,應該考慮使用StringBuffer類,它容許修改,而不是每一個不一樣的字符串都要生成一個新的對象。而且,這兩種類的對象轉換十分容易。
        同時,咱們還能夠知道,若是要使用內容相同的字符串,沒必要每次都new一個String。例如咱們要在構造器中對一個名叫s的String引用變量進行初始化,把它設置爲初始值,應當這樣作:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}

而非
s = new String("Initial Value");後者每次都會調用構造器,生成新對象,性能低下且內存開銷大,而且沒有意義,由於String對象不可改變,因此對於內容相同的字符串,只要一個String對象來表示就能夠了。也就說,屢次調用上面的構造器建立多個對象,他們的            String類型屬性s都指向同一個對象。上面的結論還基於這樣一個事實:對於字符串常量,若是內容相同,Java認爲它們表明同一個String對象。而用關鍵字new調用構造器,老是會建立一個新的對象,不管內容是否相同。        至於爲何要把String類設計成不可變類,是它的用途決定的。其實不僅String,不少Java標準類庫中的類都是不可變的。在開發一個系統的時候,咱們有時候也須要設計不可變類,來傳遞一組相關的值,這也是面向對象思想的體現。不可變類有一些優勢,好比由於它的對象是隻讀的,因此多線程併發訪問也不會有任何問題。固然也有一些缺點,好比每一個不一樣的狀態都要一個對象來表明,可能會形成性能上的問題。因此Java標準類庫還提供了一個可變版本,即StringBuffer。

相關文章
相關標籤/搜索