標籤:方法調用 輸入 結果類型 字串轉換 方法 strong 不能 靜態成員 查看
11、是否可以從一個static方法內部發出對非static方法的調用?
不可以。因為非static方法是要與對象關聯在一起的,必須建立一個對象後,才可以在該對象上進行方法調用,而static方法調用時不需要建立對象,可以直接調用。也就是說,當一個static方法被調用時,可能還沒有建立任何執行個體對象,如果從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪個對象上的呢?這個邏輯無法成立,所以,一個static方法內部發出對非static方法的調用。
12、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層的表單資料的類型。
在Hibernate中,如果將OID定義為Integer類型,那麼Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm對應檔中設定其unsaved-value屬性為0。
另外,Integer提供了多個與整數相關的操作方法,例如,將一個字串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。
13、Math.round(11.5)等於多少?Math.round(-11.5)等於多少?
Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對應。
例如,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;
14、Overload和Override的區別?Overloaded的方法是否可以改變傳回值的類型?
Overload是重載的意思,Override是覆蓋的意思,也就是重寫。
重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不同)。
重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數完全相同,通過子類建立的執行個體對象調用這個方法時,將調用子類中的定義方法,這相當於把父類中定義的那個完全相同的方法給覆蓋了,這也是物件導向編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的存取權限只能比父類的更大,不能更小。如果父類的方法是private類型,那麼,子類則不存在覆蓋的限制,相當於子類中增加了一個全新的方法。
至於Overloaded的方法是否可以改變傳回值的類型這個問題,要看你倒底想問什麼呢?這個題目很模糊。如果幾個Overloaded的方法的參數列表不一樣,它們的返回者類型當然也可以不一樣。但我估計你想問的問題是:如果兩個方法的參數列表完全一樣,是否可以讓它們的傳回值不同來實現重載Overload。這是不行的,我們可以用反證法來說明這個問題,因為我們有時候調用一個方法時也可以不定義返回結果變數,即不要關心其返回結果,例如,我們調用map.remove(key)方法時,雖然remove方法有傳回值,但是我們通常都不會定義接收返回結果的變數,這時候假設該類中有兩個名稱和參數列表完全相同的方法,僅僅是傳回型別不同,java就無法確定編程者倒底是想調用哪個方法了,因為它無法通過返回結果類型來判斷。
override可以翻譯為覆蓋,從字面就可以知道,它是覆蓋了一個方法並且對其重寫,以求達到不同的作用。對我們來說最熟悉的覆蓋就是對介面方法的實現,在介面中一般只是對方法進行了聲明,而我們在實現時,就需要實現介面聲明的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意以下的幾點:
1、覆蓋的方法的標誌必須要和被覆蓋的方法的標誌完全符合,才能達到覆蓋的效果;
2、覆蓋的方法的傳回值必須和被覆蓋的方法的返回一致;
3、覆蓋的方法所拋出的異常必須和被覆蓋方法的所拋出的異常一致,或者是其子類;
4、被覆蓋的方法不能為private,否則在其子類中只是新定義了一個方法,並沒有對其進行覆蓋。
Overload對我們來說可能比較熟悉,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入參數來區分這些方法,然後再調用時,VM就會根據不同的參數樣式,來選擇合適的方法執行。在使用重載要注意以下的幾點:
1、在使用重載時只能通過不同的參數樣式。例如,不同的參數類型,不同的參數個數,不同的參數順序(當然,同一方法內的幾個參數類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int));
2、不能通過存取權限、傳回型別、拋出的異常進行重載;
3、方法的異常類型和數目不會對重載造成影響;
4、對於繼承來說,如果某一方法在父類中是存取權限是priavte,那麼就不能在子類對其進行重載,如果定義的話,也只是定義了一個新方法,而不會達到重載的效果。
15、介面是否可繼承介面?抽象類別是否可實現(implements)介面?抽象類別是否可繼承具體類(concreteclass)?抽象類別中是否可以有靜態main方法?
介面可以繼承介面。抽象類別可以實現(implements)介面,抽象類別可以繼承具體類。抽象類別中可以有靜態main方法。
備忘:只要明白了介面和抽象類別的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支援,如果不提供的話,有什麼理由嗎?如果你沒有道理不提供,那答案就是肯定的了。
只要記住抽象類別與普通類的唯一區別就是不能建立執行個體對象和允許有abstract方法。
16、Java中實現多態的機制是什嗎?
靠的是父類或介面定義的引用變數可以指向子類或具體實作類別的執行個體對象,而程式調用的方法在運行期才動態綁定,就是引用變數所指向的具體執行個體對象的方法,也就是記憶體裡正在啟動並執行那個對象的方法,而不是引用變數的類型中定義的方法。
17、abstractclass和interface文法上有什麼區別?
1.抽象類別可以有構造方法,介面中不能有構造方法。
2.抽象類別中可以有普通成員變數,介面中沒有普通成員變數
3.抽象類別中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。
4. 抽象類別中的抽象方法的訪問類型可以是public,protected和(預設類型,雖然
eclipse下不報錯,但應該也不行),但介面中的抽象方法只能是public類型的,並且預設即為public abstract類型。
5. 抽象類別中可以包含靜態方法,介面中不能包含靜態方法
6. 抽象類別和介面中都可以包含靜態成員變數,抽象類別中的靜態成員變數的訪問類型可以任意,但介面中定義的變數只能是publicstatic final類型,並且預設即為publicstatic final類型。
7. 一個類可以實現多個介面,但只能繼承一個抽象類別。
18、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是什麼。
19、內部類可以引用它的包含類的成員嗎?有沒有什麼限制?
完全可以。如果不是靜態內部類,那沒有什麼限制!
如果你把靜態嵌套類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變數,而只能訪問外部類中的靜態成員,例如,下面的代碼:
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。
Java面試題-基礎篇二