1、Java的三種體系:
J2SE |
用於桌面開發,低端商務開發(Java to Standard Edition) ; |
J2ME |
用於移動電話、電子消費品、嵌入式開發(Java to Micro Edition) ; |
J2EE |
企業級解決方案的開發,基於WEB的開發等,(Java to Enterprise Edition) ; |
2、Java的特點:
序號 |
語言角度 |
學習角度 |
1 |
比C++簡單,放棄了對指針的使用; |
入門迅速,容易學; |
2 |
目前最好的網絡編程語言; |
編寫更少、更好的代碼; |
3 |
開放式先進的技術,可移植性強; |
更快的開發程序 |
4 |
完全的OO(面向對象,單根結構) 的跨平台語言; |
用純Java編寫的程序可以避免平台相關性; |
5 |
分布式開發,支持多線程,可靠安全健壯; |
一次編寫,處處運行,可以更容易的發布軟件; |
3、主要的開源網站:
①www.Java.net ②www.apache.org ③www.sourceforge.net
④www.theserverside.com ⑤www.javaworld.com ⑥ www.chinalab.com
4、其他技術問題:
序號 |
特征 |
|||
1 |
目前國內比較流行的技術組合:spring(www.springframework.com) + hibernate技術,還有webservice +XML技術; |
|||
2 |
J2EE的相關技術:EJB,SEVILET,JSP等; |
|||
3 |
源文件(*.java) --------->類文件(*.class) --------->java虛擬機(JVM) 編譯器 解釋器 |
|||
4 |
應用程序層 |
Java應用程序 |
||
Java平台層 |
Java虛擬機 |
|||
操作系統層 |
UNIX |
WINDOWS |
RTOS |
|
硬件層 |
SPARC |
X86 |
MIPSPPC |
二、面向對象的特征
序號 |
特征 |
||
1 |
面向對象的三個原則 |
封裝性 |
封裝的基本單元是類(class),類是一個抽象的邏輯結構,而類的對象是一個真實的物理實體;類的目的是封裝復雜性,在類內部存在隱藏實現復雜性機制; 封裝(encapsulation) 的兩個好處: 模塊化:可以獨立於其他對象的源代碼進行編寫和維護,可以很容易的將對象在系統中傳遞; 隱藏信息:其他對象可以通過本對象的一個公共接口進行通信而不影響其他對象; |
繼承性 |
繼承是一個對象獲得另一個對象的屬性的過程,繼承機制是一個對象成為一個更具通用類的一個特定實例成為可能,避免了代碼的重復編寫; |
||
多態性 |
(重載overload,方法名相同、參數的個數不同、參數的類型不同、返回的類型不同和覆蓋override) ;多態性就是“一種接口,多種方法”,可以為一組相關的動作設計一個通用的接口,其實類的函數的重載就是一種多態的體現; |
||
4 |
引入抽象編程的思想; |
類的封裝就是一種抽象思想 |
三、Java關鍵字
1、類訪問修飾符
序號 |
說明 |
1 |
類的修飾符只有public和default兩個; |
2 |
public修飾類時表示任何包的其它類都可以訪問該類; |
3 |
訪問修飾符為default時只有在同一個包里的類才能訪問它,其他包里的都不行; |
4 |
類的構造函數(構造器) 不能用final、abstract、synchronized、native、static等關鍵字進行修飾; |
2、成員訪問修飾符(public、protected、default、private)
序號 |
規則說明 |
||||
1 |
java的成員訪問修飾符有4種:public、private、protected、default |
||||
2 |
public static == static public; |
||||
3 |
類的成員訪問修飾符的詳細描述如下:(√表示允許訪問,×表示不能訪問) |
||||
visibility |
public |
protected |
default |
private |
|
訪問同一個類 |
√ |
√ |
√ |
√ |
|
訪問同一個package中不同的類 |
√ |
√ |
√ |
× |
|
訪問在不同package中的父類(superclass) |
√ |
√ |
× |
× |
|
訪問不同的package中不同的類 |
√ |
× |
× |
× |
|
綜合上表,訪問修飾符的訪問權限為:public>protected>default>private |
3、final關鍵字
序號 |
修飾范圍 |
規則說明 |
1 |
類 |
final類不能被繼承,final類的性能會有所提升如: public final class A{…} public class B extends A{…} //錯誤,A被final類不能作為B的基類 |
2 |
方法 |
final成員不能被重寫(overriding); |
3 |
類的成員變量 |
final變量不能被修改值,如: public final class A{ static final int a = 10; a = 11; //錯誤,不能被修改 static final int b; //此處是非法的,必須是如static final int b=9; } |
4 |
方法中的變量 |
可以在聲明時不賦值,但是在使用之前必須賦值,一旦賦值就不能被修改; public static void method() { Final int a; System.out.println(a) ; //錯誤,必須改為:a = 10;System.out.println(a) ; } |
5 |
final修飾的對象表示它所修飾的對象所分配的內存地址不可變; |
|
|
final和abstract不能同時使用,如public final abstract class A{}是不允許的;因為final是使類A不能被繼承而abstract是要類A在其子類中實現它的方法; |
4、abstract關鍵字
序號 |
修飾范圍 |
規則說明 |
1 |
類 |
1、 被修飾的類為抽象類,不能被實例化(生成對象) 只能作為其他類的基類(父類) 2、 abstract不能修飾類的構造函數(構造器) ; 3、 類下面的方法可以不都被修飾為abstract,沒有被修飾的方法則需要實現該方法; |
2 |
類的方法 |
修飾方法時,它的類也必須被修飾為abstract |
3 |
其它 |
abstract不能與final同時使用; |
5、static關鍵字
如果一個類的成員被聲明為static,則該成員實際上是一個全局變量,static關鍵字的使用規則如下:
序號 |
規則說明 |
1 |
在java中只有接口、最外層的類和static Inner Class可以定義static變量或方法; |
2 |
Static變量和方法屬於它的類,它的類的所有對象都可以訪問到它;但是任何一個類的對象對static變量進行修改都直接影響到所有對象; |
3 |
它們只能訪問static修飾的類的成員變量和方法 |
4 |
它們不能以任何方式引用this或super; |
6、override關鍵字
7、synchronized關鍵字
synchronized只能用在方法的聲明的前面,而變量不能用該關鍵字;
四、變量(variables statement)
1、變量聲明
序號 |
規則說明 |
||
1 |
變量名稱的命名規則: (1)java只允許英文字母以及”$”以及”_”兩個非英文字母作為變量或類名的首字母; (2)變量以小寫字母開頭,以后的每個單詞首字母大寫;其它的普通變量除了第一個單詞首字 母小寫外其他的都大寫; (3)類名的每個單詞的首字母都大寫; (4)java約定_只用在常量聲明的單詞之間分隔單詞; |
||
2 |
規則1 |
int 99year = 99是非法的,而int _99year=99是允許的 |
|
規則2 |
int myInt = 99; |
||
規則3 |
Class MyClass{} |
||
規則4 |
int MAX_VALUE = 99 |
||
3 |
當變量聲明為null時表示該變量沒有初始化即沒有分配內存空間; |
||
4 |
八進制數的聲明 |
int five = 05;int nine = 011; |
|
十六進制的聲明 |
int a = 0x9;int fifteen= 0xF;int sixteen=0x10; |
||
|
在java中除了接口、外部類和static Inner Class可以定義static變量或方法; |
2、變量作用范圍
變量聲明的位置直接決定了變量的作用范圍,它共有4種作用范圍:
序號 |
聲明范圍 |
規則說明 |
1 |
類的成員變量 |
它是一個類的成員(static修飾,所有類的變量即是所有對象公有的一個變量,它的更改將影響到所有的類的對象)或者一個對象的成員(非靜態變量,屬於類的對象的變量),它在類內,但是是在任何方法和構造函數之外; |
2 |
局部變量 |
主要是在類的方法或者一個代碼塊中,只在所在的方法或代碼塊中起作用; |
3 |
方法的參數 |
是方法或者構造器中的正式自變量,用於向方法或者構造器傳遞值,作用范圍是它所在方法或則構造器內; |
4 |
異常處理器參數 |
與參數類似,它是異常處理器的自變量; |
五、接口(Interface)
序號 |
規則說明 |
1 |
接口可以繼承接口,用關鍵字extends(擴充、繼承) |
2 |
普通類可以實現多個接口,用關鍵字implements(實現),用“,”分隔 |
3 |
接口中的定義中不能加private和protected,其default值是public; |
4 |
接口中可以定義靜態的變量,格式為:public static final type variableName; |
5 |
實現類必須實現接口中的所有方法; |
六、構造函數(構造器,constructor)
序號 |
規則說明 |
|
1 |
構造函數的作用:在生成類的對象時,為對象分配一個(封閉)的內存空間; |
|
2 |
構造函數必須與類名一致;構造函數可以重載; |
|
3 |
不管父類有無構造器,子類在實例化時都會調用父類的構造器,所以當父類中聲明了帶參數的構造器時,子類必須在構造器的第一行指定調用父類的哪個構造器; |
|
4 |
構造器不返回任何類型,可以是個空方法,也可以給類的變量賦值; |
|
5 |
在類的繼承中,子類會默認調用父類中的構造器,可能出現的情況有:
|
|
public class A{ public A(int i){ … } } |
可以將類B中加個構造器: public class B extends A{ public B(int i){super(i)} public static void main(String[] args){ B b = new B(1); } } 或者在A類中加個沒有參數和方法體的構造函數: public class A{ public A(){} public A(int i){…} } |
|
public class B extends A{ public static void main(String[] args){ B b = new B(); } } |
||
6 |
例子: public class A{ private int a; public A(){} //默認的構造函數可以不寫 public A(int i){ a= i;} //一旦建立了自己的構造函數,則java默認構造函數則將不再使用了。 } |
七、程序控制語句
1、循環控制語句
Java中共有while、do while、for三種循環語句。
序號 |
類型 |
規則說明 |
|
1 |
while |
int a =0,b=10; while(a<b){ … a++ //當a等於b時即跳出循環; } |
|
2 |
do while |
規則:先執行后判斷,至少要執行一次,如: int a =0,b=10; do{ … a++ //當a等於b時即跳出循環; } while(a<b); |
|
3 |
for |
規則根據條件執行; for(int a=0;a<10;i++){ …//當a=10時自動跳出循環; } 上個for循環語句等價於: for(int a=0;a<10;){ … //當a=10時自動跳出循環; |
a++; }甚至可以: int a=0; for(;a<10;){ … //當a=10時自動跳出循環; a++; } |
2、switch等跳轉語句
Java中共有break、continue、return三種跳轉語句,其中:
序號 |
跳轉類型 |
規則說明 |
1 |
break |
①switch語句中的跳轉; ②用來跳出循環語句; for(int i=0;i<100;i++){ if(i== 50 && j==49) break; //直接跳出循環語句 else System.out.println(i); } ③可以作為一種的先進的goto語句來使用; |
2 |
continue |
for(int i=0;i<100;i++){ if(i== 50 && j==49) continue; //直接跳轉到控制語句控制體中i++ else System.out.println(i); }在循環體語句中可以用continue語句使程序只執行滿足循環體條件的表達式; |
3 |
return |
直接結束並跳出方法,或者返回方法定義的數據類型; |
3、New運算符
理解new運算符是在運行期間為對象分配內存的是很重要的。請記住下面的話:
當一個對象引用賦值給另一個對象引用時,僅僅只是對引用的一個拷貝(即只是將2個對象都指向同一片內存。)
如下面的代碼:
public class Box{ public int length; public int height; public Box(int l,int h){ this. length = l; this. height = h; } } public class B{ Box b1= new Box(10,20); Box b2= b1; |
System.out.println (b1.length+”-“+b1.height); System.out.println (b2.length+”-“+b2.height); b1.length =20; b1.height =30; System.out.println(b1.length+”-“+b1.height); System.out.println (b2.length+”-“+b2.height); } 結果: 10-20 10-20 20-30 20-30 |
這是因為:在上面的代碼中,先是為b1分配了內存空間,然后在b2=b1時,將b2的指針也指向了b1所指向的內存空間,所以無論b1怎么變,b2都跟b1完全一致; |
4、++操作符
序號 |
分類 |
規則說明 |
1 |
優先級 |
在同一個運算表達式中,A++的優先級高於++A |
2 |
A++ |
B=A++表示B=A;A=A+1; |
3 |
++A |
B=++A表示B=A=A+1; |
八、內部類(Inner Class)
定義:inner class是 class的另一種類的成員;內部類可以實現(implement)接口或者繼承(extends)其它的類; |
||
序號 |
分類 |
規則說明 |
1 |
靜態內部類(又叫嵌套類) |
類似與類中的static成員方法,在調用該類時不需要聲明,可以直接調用; |
2 |
成員內部類 |
類似與類中的非static成員方法,在調用該類時需要實例化它的外部類,然后通過該實例在實例化該內部類 |
3 |
本地內部類(local Inner Class) |
類似於類的方法中的局部變量; |
4 |
匿名類(Anonymous Inner Class) |
一種特殊的local Inner Class; |
5 |
總之,這4種內部類類似於普通類中的靜態成員、非靜態成員、方法中的局部變量 |
1、 靜態內部類(static Inner Class)
序號 |
規則說明 |
1 |
Static inner class可以訪問它的外部類的所有的靜態成員變量和方法;而它的外部類可以訪問它的所有成員和方法(無論用什么修飾符); |
2 |
Static inner class訪問它的外部類的非static變量時只能通過它的外部類的對象實例去訪問; |
3 |
Static inner class中只能有靜態成員變量和方法; |
4 |
Static inner class的名字不能跟它的外部類相同; |
例子:public class MyOuter { public static int ins; public int myins; public static class MyInner { int i = ins; int x =myins; //不能這樣訪問外部類的非靜態成員,必須通過它的實例來訪問; int y = new MyOuter().myins; //這樣訪問myins是正確的; public void food() { …} } } 在編譯之后不僅要生成一個MyOuter.class還將生成一個MyOuter $MyInner.class; |
2、成員內部類(Member Inner Class)
序號 |
規則說明 |
|
1 |
它類似與普通類中的非靜態成員變量,但又具有類的特性,調用它需要對它實例化; |
|
2 |
它可以訪問public, package, protected, and private修飾的任何方法和成員變量; |
|
3 |
Member Inner Class不能有static變量和方法; |
|
4 |
Member Inner Class對象只能通過它的外部類的實例對象來進行訪問,如 href="#例子memInner" 例子; |
|
5 |
Member Inner Class的名字不能跟它的外部類的名字相同; |
|
6 |
inner class的聲明: A. 在outerclass內部訪問: MyInner in = new MyInner(); B. 在outer class的外部訪問: Myouter.MyInner in = new Myouter().new MyInner(); 或者 Myouter out = new Myouter(); Myouter.MyInner in = out.new MyInner(); |
|
Member Inner Class例子: public class Outer{ Public class Inner{ } } public class Test{ |
Outer ot = new Outer(); Inner inn= new Inner(); //這樣是錯誤的,不能這樣直接初始化 Outer .Inner inn= ot.new Inner(); //這樣才是正確的 } |
3、本地內部類(Local Inner Class)
序號 |
規則說明 |
1 |
Local Inner Class是定義在類的方法中或者方法的某個代碼塊中的一種類; |
2 |
類似於類的方法中的變量,不能被public, protected, private, or static修飾; |
3 |
名字不能跟外部類的名字相同;不能有static成員或方法;只能訪問它所在方法中的final變量; |
4、匿名內部類Anonymous Inner Classes
序號 |
規則說明 |
|
1 |
Anonymous Inner Classes可以說是一個沒有類名的Local Inner Class,由於沒有名字所以不需要為它定義構造器; |
|
2 |
匿名內部類只能訪問final修飾的本地變量; |
|
3 |
它總是要繼承一個類或實現一個接口(2取其1),但不需使用extends或者implement關鍵字; |
|
例子 |
public class A{ public void print(){ System.out.println(“printing A”);} } public class B{ public void print(){ A a = new A(){ //覆蓋A類中的print() public void print(){ System.out.println(“printing B”); }; //聲明一個匿名類,並將它的對象賦值給它的父類A的對象a, |
a.print(); } } public class Test{ public static void main(String[] args){ A a = new A(); B b = new B(); a.print(); b.print() } }結果是:printing A printing B |
九、String和StringBuffer類
序號 |
規則說明 |
1 |
String類與StringBuffer類的區別: a、 String類是一個final類,一旦生成對象便不可改變它的值,如果改變這個對象則相當於生成了一個新的對象(將該對象指向了一個新的內存) b、 StringBuffer類則可以創建和操作動態字符串,系統可以自動地為對象擴展內存以容納新增的文本; |
2 |
StringBuffer中的length()和capacity()方法的區別: 1)length方法返回字符串或字符串緩沖區中包含的字符數; 2)capacity方法返回分配給字符串緩沖區的空間量(capacity() = length()+16); |
3 |
String類中的equals方法與==是不一樣的,equals方法表示兩個比較的字符串中的字符是否一致,而==則表示操作符的兩邊的字符串變量所指的地址是否相同; |
4 |
1)String A=”a”+”b”+”c”; 2)StringBuffer B=new StringBuffer(“a”); B. append(“b”). append(“c”); 上面的兩個語句最后都是返回的字符串”abc”,但是1)共創建了5個字符對象(a,b,ab,c,abc),而2)中只創建了3個,節省了內存空間,效率更高; |
例子:
import java.util.*;
class StringTest{
public String hello ="Hello";
public String hel ="Hel";
public String lo ="lo";
}
class MyTest{
public MyTest(){}
public static void main(String[] args){
StringTest st = new StringTest();
String str1 ="Hello";
String str2 ="Hel";
String str3 ="lo";
String str4 ="Hel"+"lo";
String str5 =str2+str3;
String str6 =st.hel+st.lo;
System.out.println(str1==str4);
System.out.println(str1==str5);
System.out.println(str1==st.hello);
System.out.println(str1==str6);
}
}
結果:
true (str1==str4)
false (str1==str5)
true (str1==st.hello)
false (str1==str6)
十、線程(Thread)
序號 |
規則說明 |
|
1 |
定義:它是程序內的一個單一的順序控制流程; |
|
2 |
特點:多個線程可以同時運行,在一個程序內可以執行不同的任務;這正是它的神奇之處; |
|
3 |
線程與進程 |
相同點: a、 都有一個專門的單一的順序控制流程; b、 線程又被稱為輕量級進程(lightweight process);因為它在一個完整程序的上下文中運行,並利用了程序分配給它的資源和此程序的環境; |
4 |
創建一個線程的方法: (1)繼承一個Thread類,覆蓋Thread類的run()方法: public class A extends Thread(public void run(){…..}); (2)繼承一個接口Runnable來實現一個線程: public class A implements Runnable{public void run(){…..}}; 實例化一個線程: 對於(1):A a = new A(); a.start(); 對於(2):A a = new A(); Thread th = new Thread(a); th.start(); start()方法對於一個線程來說只能調用一次,如果再次start一個已經started的線程,則會拋出一個unchecked exception(IllegalThreadStateException) |
|
5 |
線程的4種狀態: |
|
|
主函數入口點,作為一個線程(main thread,主線程)在后台運行 |
十一、異常處理(Exception)
序號 |
規則說明 |
||
1 |
定義:異常是在程序執行期間中斷指令的正常流程的事件; |
||
2 |
異常有兩種: |
||
運行時異常 |
它是在java運行時系統內發生;如算術異常(被零除),指針異常(通過一個null引用訪問對象成員)、索引異常(如試圖用太大或太小的索引訪問數組中的元素) 方法不必捕獲或者指定運行時異常; |
||
非運行時異常 |
它是在java運行時系統外的代碼中發生的異常,比如輸入輸出期間的異常,它也叫被檢查的異常(checked exception) |
||
3 |
在異常處理中所涉及到的關鍵字:try、catch、throw、throws、finally |
||
4 |
構造異常處理器的步驟: a、 將可能拋出異常的語句封閉在try塊中; b、 然后在catch塊中捕獲並拋出異常(可以多個); c、 最后在finally塊中釋放在try塊中資源(可有可無,視情況而定); |
||
5 |
在程序中使用異常的優點: a、 將錯誤處理代碼與常規代碼分離; b、 將錯誤沿調用堆棧向上傳遞; c、 將錯誤類型進行分組和區分 |
||
6 |
在一個捕捉異常的句子中,必須包含try{}的語句塊,而catch和finally塊兩者必取其一或者都有,其中catch語句塊可以有多個,catch塊捕獲的異常類型必須是子類異常在前,父類在后; |
||
7 |
當try、catch和finally三塊都有時,無論在try或者catch塊中使用了return或者break也好,都將執行finally塊中的語句; |
||
8 |
在開發當中,我們一般使用finally語句塊來清除錯誤或者異常發生時的無用的內存資源; |
||
9 |
error |
在java虛擬機中發生dll鏈接故障或者其他硬故障時,jvm拋出error。典型程序不應該也不可能捕獲error。 |
|
Exception |
所有的Exception子類都是派生自Exception類; |
||
10 |
左圖中: 大的紅圈表示thirowable類的子類error和exception下的子類runtimeException都屬於uncheck Exception,小的紅圈表示exception的其它子類都屬於check Exception |
十二、集合(Collections)
1、Overriding toString()、equals()和hashCode()
序號 |
內容 |
|||||
1 |
三個方法都是都是屬於object類的public的方法,有返回值的方法; |
|||||
2 |
方法 |
返回類型 |
不覆蓋 |
覆蓋 |
||
toString() |
String |
默認返回值為: obj.getClass()+@+obj.hashCode() 其中hashCode值為無符號十六進制數; |
當需要了解對象的相關信息時,可以根據程序的要求以及對象中的字段等等去返回一個字符串; |
|||
equals() |
boolean |
在object類中,判斷是否引用對象(references)是否指向同一片內存,是則返回true; |
可以在不指向同一片內存但滿足程序需求來判斷是否返回true,否則返回false; |
|||
hashCode() |
int |
一個無符號的十六進制整數 |
覆蓋的話可以根據程序所要求的算法返回一個int類型,盡可能返回具有唯一性的值; |
|||
3 |
覆蓋一個equals()方法,要滿足以下條件: Reflexive(反自身的)即 obj.equals(obj) =true應該恆成立; Symmetric(對稱的)即obj1.equals(obj2)=true時,obj2.equals(obj1)=true; Transitive(可傳遞的)即當x.equals(y) =true 並y.equals(z) =true時x.equals(z) =true; Consistent(一致性)即如果x.equals(y) =true或者為false時無論什么時候判斷都返回相同的值; |
|||||
4 |
覆蓋一個hashCode()方法,要滿足以下條件: a、當obj1.equals(obj2)=true時,obj1.hashCode() = obj2.hashCode()恆成立; b、當obj1.hashCode() = obj2.hashCode()時,obj1.equals(obj2)不見得返回true,也有可能返回false; c、在同一個應用程序中,無論什么時候調用hashCode()方法時,返回值都必須保持一致; |
|||||
5 |
equals()和hashCode()的關系 |
|||||
方法 |
返回值 |
與hashCode()的關系 |
||||
A.equals(B) |
true |
A與B的hashCode()肯定相等; |
||||
false |
A與B的hashCode()有可能相等; |
|||||
一般在覆蓋equals()方法時都要覆蓋hashCode()方法; If two objects are equal, their hashcodes must be equal as well. |
||||||
6 |
在collections中的HashMap 和HashSet 經常用對象的hashCode值來決定它的存儲位置或者定位它的存儲位置,它有點類似與表中的primaryKey,應該盡可能的使hashCode值具有的唯一性。 |
2、Collections
序號 |
內容 |
1 |
一個implements類如果是sorted類型那么它一定是ordered類型(an implementation class can never be sorted but unordered, because sorting is a specific type of ordering) |
|
|
3、Ordered、Sorted
接口 |
Implements |
Ordered |
Sorted |
Synchronized |
屬性 |
List |
ArrayList |
√ |
× |
|
By index |
LinkedList |
√ |
|
|
By index |
|
Vector |
√ |
|
√ |
By index |
|
Set |
HashSet |
|
|
|
|
LinkedHashSet |
√ |
|
|
By insertion order or last access order |
|
TreeSet |
|
√ |
|
By natural order or common comparison rule. |
|
Map |
HashMap |
|
|
|
|
Hashtable |
|
|
√ |
|
|
LinkedHashMap |
√ |
|
|
By insertion order or last access order |
|
TreeMap |
|
√ |
|
By natural order or common comparison rule. |
4、List接口
接口 |
內容 |
||
List |
List是一個有序的集合,有時稱為序列,可以包含重復元素 |
||
ArrayList |
1、我們可以將其看作是能夠自動增長容量的數組; 2、利用toArray()返回一個數組; 3、Arrays.asList()返回一個列表; 4、迭代器(Iterator) 給我們提供了一種通用的方式來訪問集合中的元素; |
||
LinkedList |
1、LinkedList是采用雙向循環鏈表實現的。 2、利用LinkedList實現棧(stack)、隊列(queue)、雙向隊列(double-ended queue )。 |
||
Vector |
|
||
ArrayList和LinkedList的異同: |
|||
1 |
ArrayList底層采用數組完成,而LinkedList是以一般的雙向鏈表完成,其中的元素除了數據本身外,還有兩個引用,分別指向前一個元素和后一個元素。 |
||
2 |
ArrayList在遍歷時的性能要高於LinkedList,但LinkedList在增加和刪除時的性能要高於ArrayList |
||
Vector與ArrayList的區別: Vector的方法都是synchronized的(多線程安全),而ArrayList是unsynchronized的 |
5、Set接口
接口 |
內容 |
|
Set |
Set的value具有唯一性(Unique);由equals方法來決定是否存在所要加入的值; |
|
HashSet |
1、實現Set接口的hash table(哈希表),依靠HashMap來實現的。 2、我們應該為要存放到散列表的各個對象定義hashCode()和equals()。 |
|
TreeSet |
保證它里面的元素根據natural order升序或者根據自己的規則進行排序; |
|
LinkedHashSet |
它是ordered型的doubly-linked的HashSet, |
|
HashMap |
UnSynchronized for thread,允許一個null Key多個nullValue |
|
HashSet和TreeSet的比較: HashSet是基於Hash算法實現的,其性能通常都優於TreeSet。 我們通常都應該使用HashSet,在我們需要排序的功能時,我們才使用TreeSet; |
6、Map接口
接口 |
內容 |
||
Map |
Map是一個將key映射到value的對象,其中key是唯一的,每個key與value是一一對應的 |
||
HashMap |
1、它是一個unordered、unsorted的Map; 2、允許一個為null的key,同時也允許多個為null的value; |
||
Hashtable |
不允許有為null的key或value; |
||
LinkedHashtable |
Remove或者add元素的效率低於Hashtable,但遍歷的效率高於Hashtable; |
||
TreeMap |
1、保證它里面的元素根據natural order升序或者根據自己的規則進行排序; 2、並根據key值進行排序; |
||
Hashtable是一個synchronized的HashMap |
|||
HashMap和TreeMap的異同: HashMap的速度通常都比TreeMap快,只有在需要排序的功能的時候,才使用TreeMap。 |
|||
HashMap和Hashtable的異同: |
|||
1. |
Hashtable是Dictionary的子類,HashMap是Map接口的一個實現類; |
||
2. |
Hashtable中的方法是同步的,而HashMap中的方法在缺省情況下是非同步的。即是說,在多線程應用程序中,不用專門的操作就安全地可以使用Hashtable了;而對於HashMap,則需要額外的同步機制。但HashMap的同步問題可通過Collections的一個靜態方法得到解決:Map Collections.synchronizedMap(Map m) , 這個方法返回一個同步的Map,這個Map封裝了底層的HashMap的所有方法,使得底層的HashMap即使是在多線程的環境中也是安全的。 |
||
3. |
在HashMap中,可以允許唯一的一個null值作為鍵;但可以有一個或多個value值為null。當get()方法返回null值時,即可以表示HashMap中沒有該鍵,也可以表示該鍵所對應的值為null。因此,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵,而應該用containsKey()方法來判斷。 |
||
Map中的key是唯一的; HashMap對key進行散列, TreeMap按照key進行排序。 |
十三、Socket編程
1、什么是socket?
所謂socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。
Socket和ServerSocket類庫位於java.net包中。ServerSocket用於服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對於一個網絡連接來說,套接字是平等的,並沒有差別,不因為在服務器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。
2、重要的Socket API:
java.net.Socket繼承於java.lang.Object,有八個構造器,其方法並不多,下面介紹使用最頻繁的三個方法:
1 |
. Accept方法用於產生"阻塞",直到接受到一個連接,並且返回一個客戶端的Socket對象實例。"阻塞"是一個術語,它使程序運行暫時"停留"在這個地方,直到一個會話產生,然后程序繼續;通常"阻塞"是由循環產生的。 |
2 |
. getInputStream方法獲得網絡連接輸入,同時返回一個IntputStream對象實例,。 |
3 |
. getOutputStream方法連接的另一端將得到輸入,同時返回一個OutputStream對象實例。 |
注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因為它們返回的流對象,通常都會被另一個流對象使用。 |
3、如何開發一個Server-Client模型的程序?
開發原理:
服務器,使用ServerSocket監聽指定的端口,端口可以隨意指定(由於1024以下的端口通常屬於保留端口,在一些操作系統中不可以隨意使用,所以建議使用大於1024的端口),等待客戶連接請求,客戶連接后,會話產生;在完成會話后,關閉連接。
客戶端,使用Socket對網絡上某一個服務器的某一個端口發出連接請求,一旦連接成功,打開會話;會話完成后,關閉Socket。客戶端不需要指定打開的端口,通常臨時的、動態的分配一個1024以上的端口。
//建立服務端
import java.net.*;
import java.io.*;
public class Server {
private ServerSocket ss;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Server() {
try {
ss = new ServerSocket(10000);
while (true) {
socket = ss.accept();
in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
String line = in.readLine();
out.println("you input is :" + line);
out.close();
in.close();
socket.close();
}
ss.close();
} catch (IOException e) {
}
}
public static void main(String[] args) {
new Server();
}
}
這個程序建立了一個服務器,它一直監聽10000端口,等待用戶連接。在建立連接后給客戶端返回一段信息,然后結束會話。這個程序一次只能接受一個客戶連接。
//建立客戶端
import java.io.*;
import java.net.*;
public class Client {
Socket socket;
BufferedReader in;
PrintWriter out;
public Client() {
try {
socket = new Socket("xxx.xxx.xxx.xxx", 10000);
in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader line = new BufferedReader(new InputStreamReader( System.in));
out.println(line.readLine());
line.close();
out.close();
in.close();
socket.close();
} catch (IOException e) {
}
}
public static void main(String[] args) {
new Client();
}
}
十四、接口與抽象類的異同
相同點:1、均不能生成實例(不能使用new生成實例)
2、可以聲明變量,但必須指向子類或者實現類的對象(即不能為private)
3、在接口中可以聲明一個標記接口(即沒有任何方法聲明,表示具有某種功能)
在抽象類中可以聲明一個沒有抽象方法的抽象類
不同點:1、java只允許子類有一個父類,不允許多重繼承,但子類可以實現多個接口
2、接口比抽象類應用更廣泛、靈活
3、接口內不能有任何實例字段,但抽象類可以有實例字段以及實現了的方法
4、接口內的所有方法默認為public,而抽象類必須手動標識
5、繼承類不必實現抽象類中的所有abstract方法,而實現類必須實現接口中的所有方法
十五、在實際應用開發中怎樣抽象一個類?
確定類的方法就是尋找需求分析中的名詞,另一方面主要是與需求分析中的動詞相對應。在實際的開發中只有依靠經驗才能確定究竟哪些名詞與名詞是必須的。
附錄----類的設計技巧:
1、 永遠保持數據私有;
2、 永遠初始化數據;
3、 在一個類中不要過多的使用基本數據類型,要盡可能的封裝;
4、 盡量使類的功能單一化;
十六、throw與throws的區別
1、 throw代表動作,表示拋出一個異常的動作;throws代表一種狀態,代表可能拋出的異常;
2、 throw用在方法中實現,而throws用在方法的聲明中;
3、 throw只能用在拋出一種異常,而throws可以拋出多個異常。
十七、this的用法:
1) this只能用在一個實例當中,而不能用在static方法中;
2) this是當前執行對象的引用,換句話說:這個對象的引用主要是用來調用正在運行的方法;
3) this可以作為一個方法的參數來調用;
十八、JDBC
1、 數據庫驅動程序和URL:
數據庫名 |
驅動程序 |
URL |
MSSQL Server2000 |
com.microsoft.jdbc.sqlserver.SQLServerDriver |
jdbc:microsoft:sqlserver://[ip]:[port];databaseName=[databaseName] |
JDBC-ODBC(Access) |
sun.jdbc.odbc.JdbcOdbcDriver |
jdbc:odbc:[odbcsource] |
Oracle oci8 |
oracle.jdbc.driver.OracleDriver |
jdbc:oracle:oci8:@ [ip]:[port]:[sid] |
Oracle thin Driver |
oracle.jdbc.driver.OracleDriver |
jdbc:oracle:thin:@[ip]:[port]:[sid] |
MySQL |
org.gjt.mm.mysql.Driver |
jdbc:mysql://ip/database |
Cloudscape |
COM.cloudscape.core.JDBCDriver |
jdbc:cloudscape:database |
2、 數據連接:Connection con = DriverManager.getConnection(url,username,password);
3、 建立會話:Statement st = con.createStatement();
其他知識點:
1、 接口中的變量默認修飾符為:public static final;
2、 所有類的實例都共享類的static的方法和變量,任何該類的對象對static變量的改變,都將影響到其他的對象;
3、 包外的子類只能通過繼承的方式去訪問包里的父類中protected成員而不能通過父類的實例去訪問。同一個包中的任何類都可以訪問一個類中的protected成員。英文原文:
For subclass outside the package, the protected member can be accessed only through inheritance, a subclass outside the package can’t access a protected member by using a reference to an instance of the superclass ,in other words, inheritance is the only mechanism for a subclass outside package to access a protected member of its superclass.
4、 OOAD:面向對象的分析設計(Object Oriented Analysis Design)
5、 Java的數組(Array)、Vector、ArrayList、HashMap的異同
序號 |
異同 |
1 |
array(數組)和Vector是十分相似的Java構件(constructs),兩者全然不同,在選擇使用時應根據各自的功能來確定。 Array:arrays的元素個數不能下標越界,保證了Java程序的安全性。 Array可以存放Object和基本數據類型,但創建時必須指定數組的大小,並不能再改變。值得注意的是:當Array中的某一元素存放的是Object reference 時,Java將其初值設為null。 |
2 |
Vector:當更多的元素被加入進來以至超出其容量時,Vector的size會動態增長,而Array容量是定死的。同時,Vector在刪除一些元素后,其所有下標大於被刪除元素的元素都依次前移,並獲得新下標比原來的小了。注意:當調用Vector的size()方法時,返回Vector中實際元素的個數。 Vector內部也是通過元素的整數索引來訪問元素,但它只能存Object對象,不能用於存放基本類型數據,比如要存放一個整數10,得用Integer包裝類對象再放進去。當Vector中的元素個數發生變化時, 其內部的Array必須重新分配並進行拷貝。 Vector同時也實現了List接口,所以也可以算作Collection了,只是它還特殊在:Vector is synchronized。即Vector對象自身實現了同步機制。 |
3 |
ArrayList:實現了List接口,功能與Vector一樣,只是沒有同步機制(ArrayList is not synchronized。),當然元素的訪問方式為從List中繼承而來,可存放任何類型的對象。 |
4 |
HashMap類繼承了Map接口,實現用Keys來存儲和訪問Values,Keys和Values都可以為空,而Hashtable類的Keys不能為null,並Hashtable類有同步機制控制,而HashMap類沒有。 |