可以有多個類,但隻能有一個public的類,并且public的類名必須與檔案名相一緻。
java中的保留字,現在沒有在java中使用。
&和&&都可以用作邏輯與的運算符,表示邏輯與(and),當運算符兩邊的表達式的結果都為true時,整個運算結果才為true,否則,隻要有一方為false,則結果為false。
&&還具有短路的功能,即如果第一個表達式為false,則不再計算第二個表達式,例如,對于if(str != null && !str.equals(“”))表達式,當str為null時,後面的表達式不會執行,是以不會出現NullPointerException如果将&&改為&,則會抛出NullPointerException異常。If(x==33 & ++y>0) y會增長,If(x==33 && ++y>0)不會增長
&還可以用作位運算符,當&操作符兩邊的表達式不是boolean類型時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來擷取該整數的最低4個bit位,例如,0x31 & 0x0f的結果為0x01。
在switch(expr1)中,expr1隻能是一個整數表達式或者枚舉常量,整數表達式可以是int基本類型或Integer包裝類型,由于,byte,short,char都可以隐含轉換為int,是以,這些類型以及這些類型的包裝類型也是可以的。顯然,long和String類型都不符合switch的文法規定,并且不能被隐式轉換成int類型,是以,它們不能作用于swtich語句中。
對于short s1 = 1; s1 = s1 + 1; 由于s1+1運算時會自動提升表達式的類型,是以結果是int型,再指派給short類型s1時,編譯器将報告需要強制轉換類型的錯誤。
對于short s1 = 1; s1 += 1;由于 += 是java語言規定的運算符,java編譯器會對它進行特殊處理,是以可以正确編譯。
char型變量是用來存儲Unicode編碼的字元的,unicode編碼字元集中包含了漢字,是以,char型變量中當然可以存儲漢字啦。不過,如果某個特殊的漢字沒有被包含在unicode編碼字元集中,那麼,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼占用兩個位元組,是以,char類型的變量也是占用兩個位元組。
使用final關鍵字修飾一個變量時,是指引用變量不能變,引用變量所指向的對象中的内容還是可以改變的。
例如,對于如下語句:
final StringBuffer a=new StringBuffer("immutable");
執行如下語句将報告編譯期錯誤:
a=new StringBuffer("");
但是,執行如下語句則可以通過編譯:
a.append(" broken!");
有人在定義方法的參數時,可能想采用如下形式來阻止方法内部修改傳進來的參數對象:
public void method(final StringBuffer param){
}
實際上,這是辦不到的,在該方法内部仍然可以增加如下代碼來修改參數對象:
param.append("a");
“==”操作符專門用來比較兩個變量的值是否相等,也就是用于比較變量所對應的記憶體中所存儲的數值是否相同,要比較兩個基本類型的資料或兩個引用變量是否相等,隻能用==操作符。
如果一個變量指向的資料是對象類型的,那麼,這時候涉及了兩塊記憶體,對象本身占用一塊記憶體(堆記憶體),變量也占用一塊記憶體(棧記憶體),例如Objet obj = new Object();變量obj是一個記憶體,new Object()是另一個記憶體,此時,變量obj所對應的記憶體中存儲的數值就是對象占用的那塊記憶體的首位址。對于指向對象類型的變量,如果要比較兩個變量是否指向同一個對象,即要看這兩個變量所對應的記憶體中的數值是否相等,這時候就需要用==操作符進行比較。
equals方法是用于比較兩個獨立對象的内容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的。例如,對于下面的代碼:
String a=new String("foo");
String b=new String("foo");
兩條new語句建立了兩個對象,然後用a,b這兩個變量分别指向了其中一個對象,這是兩個不同的對象,它們的首位址是不同的,即a和b中存儲的數值是不相同的,是以,表達式a==b将傳回false,而這兩個對象中的内容是相同的,是以,表達式a.equals(b)将傳回true。
在實際開發中,我們經常要比較傳遞進行來的字元串内容是否等,例如,String input = …;input.equals(“quit”),許多人稍不注意就使用==進行比較了,這是錯誤的,記住,字元串的比較基本上都是使用equals方法。
如果一個類沒有自己定義equals方法,那麼它将繼承Object類的equals方法,Object類的equals方法的實作代碼如下:
boolean equals(Object o){
return this==o;
}
這說明,如果一個類沒有自己定義equals方法,它預設的equals方法(從Object 類繼承的)就是使用==操作符,也是在比較兩個變量指向的對象是否是同一對象,這時候使用equals和使用==會得到同樣的結果,如果比較的是兩個獨立的對象則總傳回false。如果你編寫的類希望能夠比較該類建立的兩個執行個體對象的内容是否相同,那麼你必須覆寫equals方法,由你自己寫代碼來決定在什麼情況即可認為兩個對象的内容是相同的。
在文法定義上的差別:靜态變量前要加static關鍵字,而執行個體變量前則不加。
在程式運作時的差別:執行個體變量屬于某個對象的屬性,必須建立了執行個體對象,其中的執行個體變量才會被配置設定空間,才能使用這個執行個體變量。靜态變量不屬于某個執行個體對象,而是屬于類,是以也稱為類變量,隻要程式加載了類的位元組碼,不用建立任何執行個體對象,靜态變量就會被配置設定空間,靜态變量就可以被使用了。總之,執行個體變量必須建立對象後才可以通過這個對象來使用,靜态變量則可以直接使用類名來引用。
例如,對于下面的程式,無論建立多少個執行個體對象,永遠都隻配置設定了一個staticVar變量,并且每建立一個執行個體對象,這個staticVar就會加1;但是,每建立一個執行個體對象,就會配置設定一個instanceVar,即可能配置設定多個instanceVar,并且每個instanceVar的值都隻自加了1次。
public class VariantTest{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest(){
staticVar++;
instanceVar++;
System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar);
}
不可以。因為非static方法是要與對象關聯在一起的,必須建立一個對象後,才可以在該對象上進行方法調用,而static方法調用時不需要建立對象,可以直接調用。也就是說,當一個static方法被調用時,可能還沒有建立任何執行個體對象,如果從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪個對象上的呢?這個邏輯無法成立,是以,一個static方法内部不可以發出對非static方法的調用。
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中還定義了表示整數的最大值和最小值的常量。
這四個作用域的可見範圍如下表所示。
說明:如果在修飾的元素上面沒有寫任何通路修飾符,則表示friendly。
Overload是重載的意思,Override是覆寫的意思,也就是重寫。
重載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的參數清單各不相同(即參數個數或類型不同)。
重寫Override表示子類中的方法可以與父類中的某個方法的名稱和參數完全相同,通過子類建立的執行個體對象調用這個方法時,将調用子類中的定義方法,這相當于把父類中定義的那個完全相同的方法給覆寫了,這也是面向對象程式設計的多态性的一種表現。子類覆寫父類的方法時,隻能比父類抛出更少的異常,或者是抛出父類抛出的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的通路權限隻能比父類的更大,不能更小。如果父類的方法是private類型,那麼,子類則不存在覆寫的限制,相當于子類中增加了一個全新的方法。
至于Overloaded的方法是否可以改變傳回值的類型這個問題,要看你倒底想問什麼呢?這個題目很模糊。如果幾個Overloaded的方法的參數清單不一樣,它們的傳回者類型當然也可以不一樣。但我估計你想問的問題是:如果兩個方法的參數清單完全一樣,是否可以讓它們的傳回值不同來實作重載Overload?這是不行的,我們可以用反證法來說明這個問題,因為我們有時候調用一個方法時也可以不定義傳回結果變量,即不要關心其傳回結果,例如,我們調用map.remove(key)方法時,雖然remove方法有傳回值,但是我們通常都不會定義接收傳回結果的變量,這時候假設該類中有兩個名稱和參數清單完全相同的方法,僅僅是傳回類型不同,java就無法确定程式設計者倒底是想調用哪個方法了,因為它無法通過傳回結果類型來判斷。
override可以翻譯為覆寫,從字面就可以知道,它是覆寫了一個方法并且對其重寫,以求達到不同的作用。對我們來說最熟悉的覆寫就是對接口方法的實作,在接口中一般隻是對方法進行了聲明,而我們在實作時,就需要實作接口聲明的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆寫父類中的方法,在覆寫要注意以下的幾點:
1、覆寫的方法的标志必須要和被覆寫的方法的标志完全比對,才能達到覆寫的效果;
2、覆寫的方法的傳回值必須和被覆寫的方法的傳回一緻;
3、覆寫的方法所抛出的異常必須和被覆寫方法的所抛出的異常一緻,或者是其子類;
4、被覆寫的方法不能為private,否則在其子類中隻是新定義了一個方法,并沒有對其進行覆寫。
overload對我們來說可能比較熟悉,可以翻譯為重載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入參數來區分這些方法,然後再調用時,VM就會根據不同的參數樣式,來選擇合适的方法執行。在使用重載要注意以下的幾點:
在使用重載時隻能通過不同的參數樣式。例如,不同的參數類型,不同的參數個數,不同的參數順序(當然,同一方法内的幾個參數類型必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int));
不能通過通路權限、傳回類型、抛出的異常進行重載;
方法的異常類型和數目不會對重載造成影響;
對于繼承來說,如果某一方法在父類中是通路權限是priavte,那麼就不能在子類對其進行重載,如果定義的話,也隻是定義了一個新方法,而不會達到重載的效果。
is-a表示的是屬于的關系。比如兔子屬于一種動物(繼承關系)。
has-a表示組合,包含關系。比如兔子包含有腿,頭等元件。
jvm裡有多個類加載器,每個類加載器可以負責加載特定位置的類,例如,bootstrap類加載負責加載jre/lib/rt.jar中的類, 我們平時用的jdk中的類都位于rt.jar中。extclassloader負責加載jar/lib/ext/*.jar中的類,appclassloader負責classpath指定的目錄或jar中的類。除了bootstrap之外,其他的類加載器本身也都是java類,它們的父類是ClassLoader。
把各個功能按調用流程進行了子產品化,子產品化帶來的好處就是可以随意組合,舉例說明:如果要注冊一個使用者,流程為顯示界面并通過界面接收使用者的輸入,接着進行業務邏輯處理,在處理業務邏輯又通路資料庫,如果我們将這些步驟全部按流水帳的方式放在一個方法中編寫,這也是可以的,但這其中的壞處就是,當界面要修改時,由于代碼全在一個方法内,可能會碰壞業務邏輯和資料庫通路的碼,同樣,當修改業務邏輯或資料庫通路的代碼時,也會碰壞其他部分的代碼。分層就是要把界面部分、業務邏輯部分、資料庫通路部分的代碼放在各自獨立的方法或類中編寫,這樣就不會出現牽一發而動全身的問題了。這樣分層後,還可以友善切換各層,譬如原來的界面是Swing,現在要改成BS界面,如果最初是按分層設計的,這時候不需要涉及業務和資料通路的代碼,隻需編寫一條web界面就可以了。
分層的好處:
1.實作了軟體之間的解耦;
2.便于進行分工
3.便于維護
4.提高軟體元件的重用
5.便于替換某種産品,比如持久層用的是hibernate,需要更換産品用toplink,就不用該其他業務代碼,直接把配置一改。
6.便于産品功能的擴充。
7.便于适用使用者需求的不斷變化
hashcode這個方法是用來鑒定2個對象是否相等的。
equals方法和hashCode方法這2個方法都是用來判斷2個對象是否相等的,但是他們是有差別的。
一般來講,equals這個方法是給使用者調用的,如果你想判斷2個對象是否相等,你可以重寫equals方法,然後在代碼中調用,就可以判斷他們是否相等了。簡單來講,equals方法主要是用來判斷從表面上看或者從内容上看,2個對象是不是相等。舉個例子,有個學生類,屬性隻有姓名和性别,那麼我們可以認為隻要姓名和性别相等,那麼就說這2個對象是相等的。
hashcode方法一般使用者不會去調用,比如在hashmap中,由于key是不可以重複的,他在判斷key是不是重複的時候就判斷了hashcode這個方法,而且也用到了equals方法。這裡不可以重複是說equals和hashcode隻要有一個不等就可以了!是以簡單來講,hashcode相當于是一個對象的編碼,就好像檔案中的md5,他和equals不同就在于他傳回的是int型的,比較起來不直覺。我們一般在覆寫equals的同時也要覆寫hashcode,讓他們的邏輯一緻。舉個例子,還是剛剛的例子,如果姓名和性别相等就算2個對象相等的話,那麼hashcode的方法也要傳回姓名的hashcode值加上性别的hashcode值,這樣從邏輯上,他們就一緻了。
要從實體上判斷2個對象是否相等,用==就可以了,如果兩個對象的實體(記憶體)位址相等,那麼這兩個對象肯定就是同一個對象。
所謂AOP,即Aspect orientied program,就是面向方面(切面)的程式設計。
面向切面程式設計Aspect-Orlented-Programming,即AOP是對面向對象的思維方式的有力補充。
AOP的好處是可以動态地添加和删除在切面上的邏輯而不影響原來的執行代碼
所謂方面(切面),指的是貫穿到系統的各個子產品中的系統一個功能就是一個方面(切面),比如,記錄日志,統一異常處理,事務處理,權限檢查,這些功能都是軟體系統的一個面,而不是一點,在各個子產品中都要出現。
把系統的一個方面的功能封裝成對象的形式來處理就是面向方面(切面)程式設計
把功能子產品對應的對象作為切面嵌入到原來的各個系統子產品中,采用代理技術,代理會調用目标,同時把切面功能的代碼(對象)加入進來。是以,用spring配置代理對象時隻要要配兩個屬性,分别表示目标和切面對象(Advisor)。
MVC是Model—View—Controler的簡稱。即模型—視圖—控制器。MVC是一種設計模式,它強制性的把應用程式的輸入、處理和輸出分開。
MVC中的模型、視圖、控制器它們分别擔負着不同的任務。
視圖: 視圖是使用者看到并與之互動的界面。視圖向使用者顯示相關的資料,并接受使用者的輸入。視圖不進行任何業務邏輯處理。
模型: 模型表示業務資料和業務處理。相當于JavaBean。一個模型能為多個視圖提供資料。這提高了應用程式的重用性
控制器: 當使用者單擊Web頁面中的送出按鈕時,控制器接受請求并調用相應的模型去處理請求。然後根據處理的結果調用相應的視圖來顯示處理的結果。
MVC的處理過程:首先控制器接受使用者的請求,調用相應的模型來進行業務處理,并傳回資料給控制器。控制器調用相應的視圖來顯示處理的結果。并通過視圖呈現給使用者。