工作原理
1)編寫.java文本文件;
2)通過(guò)編譯器編譯為.class二進(jìn)制文件;
3)使用JAVA虛擬機(jī)執(zhí)行.class文件,不同平臺(tái)對(duì)應(yīng)不同虛擬機(jī);
System.exit:main方法結(jié)束不等于整個(gè)程序的真正結(jié)束,可能還有線程在運(yùn)行著,調(diào)用System.exit()才達(dá)到程序的真正結(jié)束。
面向?qū)ο笤?/strong>
單繼承,多接口實(shí)現(xiàn);一般,繼承主要用在一個(gè)系列的對(duì)象抽象;接口主要針對(duì)功能的抽象;
JAVA語(yǔ)言中,并非所有的變量都是對(duì)象,基本的數(shù)值類型(char,short,int,long,float,double,boolean)除外,可能是為了運(yùn)行速度,編譯器沒(méi)有將這些類型編譯為對(duì)象;
對(duì)象Object是所有對(duì)象的祖宗;
對(duì)象Class保存一個(gè)對(duì)象的類型信息,也可以是基本的數(shù)值類型;
數(shù)據(jù)類型
int 4B
short 2B
long 8B
byte 1B
float 4B (后綴f,F)
double 8B (后綴d,D)
char 2B
boolean 1B
前綴:
0x:十六進(jìn)制 (指數(shù)用p,十進(jìn)制用e)
0:八進(jìn)制
變量命名
字母(a-zA-Z)、下劃線(_)開(kāi)頭,后續(xù)字母可以是字母、數(shù)字、下劃線,不能是關(guān)鍵字或者保留字。
關(guān)鍵字
abstract, assert, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, extends, final, finally, float, for, goto, if,
implements, import, instanceof, int, interface, long, native, new, null, package, private, protected, public, return, short, static, strictfp, super, switch,
synchronized, this, throw, throws, transient, try, void, volatile, while
其中,const和goto是保留關(guān)鍵字。
注釋
//行注釋
運(yùn)算符
算術(shù)運(yùn)算:+、-、*、/、%;++、--、+=、-=;
關(guān)系運(yùn)算:>、<、==、>=、<=、!=、!、&&、||;
位運(yùn)算:&、|、^、~、>>、>>>、<<、<<<;
流程控制
if ... else ...
(...) ? ... : ...;
switch 只能接受byte、short、char、int四種,不能接受long類型。
for
for each
while
do...while
參數(shù)傳遞
基本數(shù)據(jù)類型按照值傳遞,對(duì)象按照引用傳遞;String對(duì)象沒(méi)有修改該對(duì)象的方法,如果要通過(guò)引用修改可以使用StringBuilder或StringBuffer;
面向?qū)ο?br />類加載:static字段、一般字段、構(gòu)造函數(shù)字段;(注意:static成員是類加載器加載的,是線程安全的;)
繼承;
接口;
內(nèi)部類、匿名內(nèi)部類用途:使用一個(gè)對(duì)象去做任務(wù)處理,但是該對(duì)象以后也不需要用到;這樣在一個(gè)類A內(nèi)部定義一個(gè)內(nèi)部類B,這樣類B可以訪問(wèn)類A的數(shù)據(jù),外界并不知道有類B的存在;
異常繼承時(shí)候,父類與子類的異常聲明可以不同,但是子類的異常必須在父類的異常范圍之內(nèi),也就是父類的異常必須可以引用子類的異常;
方法繼承時(shí)候,如果需要覆蓋,方法名稱、形參類型、返回類型必須相同;
訪問(wèn)修飾符
當(dāng)前對(duì)象 同一個(gè)包中子類/非子類 其它包中子類/非子類
private yes no/no no/no
protected yes yes/yes yes/no
默認(rèn) yes yes/yes no/no
public yes yes/yes yes/yes
對(duì)象比較
使用==比較的是引用;使用equals默認(rèn)比較的也是對(duì)象的引用,但是,經(jīng)過(guò)重載的equals可以按照我們需要去比較特點(diǎn)字段;
String類重載了equals與hashCode,而StringBuilder與StringBuffer沒(méi)有經(jīng)過(guò)重載,因此使用equals比較StringBuilder與StringBuffer實(shí)際比較的是引用;
注意:重載equals必須同時(shí)重載hashCode,這兩個(gè)方法必須保持同步,即equals與hashCode同真假;
對(duì)象序列化
繼承接口Serializable即可以實(shí)現(xiàn)對(duì)象序列化,默認(rèn)是序列化與反序列化的結(jié)果是相同的(引用被序列化后再反序列化回來(lái)還是跟之前相同的);
一般序列化后,要定義字段serialVersionUID,eclipse自動(dòng)可以生成;作用是保持序列化與反序列化時(shí)候的版本兼容,如果不定義該字段,當(dāng)出現(xiàn)反序列化時(shí)候內(nèi)容不同時(shí),可能會(huì)報(bào)錯(cuò);
transient關(guān)鍵字可以使該字段不進(jìn)行序列化;
對(duì)象克隆
繼承接口Cloneable,然后覆蓋Object類的clone()方法進(jìn)行克隆的聲明;默認(rèn)是淺拷貝,若字段是引用類型,則需要手動(dòng)在clone()方法里面人工進(jìn)行new一個(gè)對(duì)象;
數(shù)組默認(rèn)支持克隆,但是數(shù)組的數(shù)組(二維數(shù)組以上)不支持直接使用克??;
異常
異常的結(jié)構(gòu)
Throwable
| |
Error Exception
| |
IOException等 RuntimeException
異常的分類
1)未檢查異常
RuntimeException和Error及其子類。
這類異常不需要顯式捕捉,一旦發(fā)生,它自動(dòng)會(huì)拋出來(lái),然后程序終止;當(dāng)然,你也可以進(jìn)行捕捉,這樣程序就可以繼續(xù)運(yùn)行;
2)已檢查異常
Exception及其子類
由于Exception派生的子類及Exception類多是已檢查異常,所以,Throwable類也屬于已檢查異常;這類異常必須進(jìn)行捕捉,否則編譯不能通過(guò)。
聲明已檢查異常
例:public FileInputStream(String name) throws FileNotFoundException
拋出已檢查異常
例:throw new Exception("message");
捕獲異常
如果不捕獲的話,程序就會(huì)終止。有些時(shí)候,出現(xiàn)了異常,但是,我們不需要終止程序,那么就需要捕獲異常。
try {
// 可能拋出異常的代碼
} catch(異常類型 e) {
// e.printStackTrace(); // 打印異常堆棧
// 處理
}
// catch語(yǔ)句是從上到下執(zhí)行的,具體的異常應(yīng)該放在上面;
傳遞異常
將異常傳遞下去,這樣才能不會(huì)被覆蓋;
try {
// access the database
} catch(SQLException e) {
throw new ServletException("database error.", e);
}
finally子句
finally子句是一定會(huì)執(zhí)行的,該子句主要用于回收一些資源。
泛型(屬于底層代碼,不常用)
JAVA虛擬機(jī)中沒(méi)有泛型,只有普通類與方法,使用泛型主要是為了方便類型轉(zhuǎn)換;還有泛型可以限定對(duì)象引用的使用;所有,泛型了解使用即可,不需要深究;
泛型包含兩種:泛型類、泛型方法;泛型類主要用于對(duì)某個(gè)不確定類型的字段進(jìn)行操作;泛型方法是指static方法中使用了泛型參數(shù);
泛型的翻譯
翻譯泛型表達(dá)式
A a = new A();
a.setT("generic programming.");
String str = a.getT(); // 翻譯為:String str = (String) a.getT();
翻譯泛型方法
public static T getMiddle(T[] a) // 翻譯為:public static Object getMiddle(Object[] objects)
public static T getMiddle(T[] a) // 翻譯為:public static Comparable getMiddle(Comparable[] a)
// 默認(rèn)是轉(zhuǎn)化為左邊第一個(gè)類型,所有盡量將范圍大的類型放到前面;
復(fù)雜一點(diǎn)的橋方法:
class A {
private T t;
public void setT(T t) {
this.t = t;
}
public T getT() {
return t;
}
}
class B extends A {
public void setT(String t) {
super.setT(t);
}
}
// 翻譯后:
class A { // 父類翻譯后肯定是Object
private Object t;
public void setT(Object object) {
t = object;
}
public Object getT() {
return t;
}
}
class B extends A {
public void setT(String string) { // 子類肯定它的父類是String
super.setT(string);
}
public volatile void setT(Object object) { // 橋方法,外界還是認(rèn)為是Object
setT((String) object);
}
}
// 調(diào)用:
A a = new B();
a.setT("generic programming."); // 翻譯為:b.setT((Object) "generic programming.");
不能使用泛型的情況
不能使用泛型繼承異常。
例如:public class Problem extends Exception {...}。
不能在catch(...)中,使用catch(T t)。
異常聲明中可以使用泛型。
例如:public static void doWork(T t) throws T {...}。
不能用泛型數(shù)組
A[] arr = new A[5]; // 擦除后為:A[] arr = new A[5];
不能將泛型類型實(shí)例化。
class A {
a = new T(); // 擦除后是a = new Object();我們本意卻不是這個(gè)。
...
}
類的靜態(tài)字段不能使用泛型;
當(dāng)泛型類型擦除后,創(chuàng)建條件不能產(chǎn)出沖突。
例如:public boolean equals(T t) {...}
類型限定
子類型限定<? extends Employee>,可以讀,不能寫。
Pair<? extends Employee> pair1 = null; // ?是Employee的子類,子類可能很多,不確定有幾個(gè)。
Pair<Manager> pair2 = new Pair<Manager>();
pair1 = pair2;
pair1.getFirst(); // 操作成功,因?yàn)槭?#8220;(? extends Employee) pair1.getFirst();”,
// 相當(dāng)于是“(Employee) pair1.getFirst();”。
pair1.setFirst(new Manager()); // 編譯通不過(guò),因?yàn)槭?#8220;pair1.setFirst(? extends Employee);”
// 相當(dāng)于是“pair1.setFirst(?);” 不確定的類型。
超類型限定<? super Employee>,可以寫,不能讀;剛好和上面相反。
無(wú)限定通配符<?>,可以讀,不能寫;讀的時(shí)候直接轉(zhuǎn)型為Object。
反射(屬于底層代碼,不常用)
對(duì)象產(chǎn)生于類,而在JAVA虛擬機(jī)里面還保存著對(duì)類的描述,這個(gè)描述是一個(gè)Class的對(duì)象;類信息被加載到虛擬機(jī),就會(huì)產(chǎn)生一個(gè)Class對(duì)象,用以描述這個(gè)類的信息;
通過(guò)這個(gè)Class對(duì)象可以解析類的結(jié)構(gòu),這個(gè)Class對(duì)象可以從類信息來(lái)(例如:Employee.class),也可以從對(duì)象來(lái)(例如:emp.getClass());
通過(guò)這個(gè)Class對(duì)象可以引用具體對(duì)象的字段、方法、構(gòu)造器,可以完全操作一個(gè)對(duì)象;
.class: 應(yīng)該是一個(gè)指向類的Class對(duì)象的指針。
forName(): 會(huì)調(diào)用當(dāng)前線程所在的ClassLoader來(lái)裝載一個(gè)類的Class實(shí)例。
注意:基礎(chǔ)類型也可以這樣使用“int.class”;
類加載器(屬于底層代碼,不常用)
java中的類是動(dòng)態(tài)加載的,即引用到了才會(huì)被加載;
// 三種加載方式示例
class A{}
class B{}
class C{}
public class Loader{
public static void main(String[] args) throws Exception{
Class aa=A.class;
Class bb=Class.forName("B");
Class cc=ClassLoader.getSystemClassLoader().loadClass("C");
}
}
系統(tǒng)內(nèi)默認(rèn)的類加載器
Bootstrap ClassLoader (加載rt.jar)
|
ExtClassLoader (加載jre/lib/ext/)
|
AppClassLoader (加載claspath)
//ClassLoader實(shí)現(xiàn):查找類,從父加載器向上遍歷,找不到就調(diào)用當(dāng)前自定義的加載器;
protected ClassLoader() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
// 自己實(shí)現(xiàn)的類加載器,默認(rèn)是用系統(tǒng)類加載器的。
this.parent = getSystemClassLoader();
initialized = true;
}
protected ClassLoader(ClassLoader parent) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
// 傳入一個(gè)父加載器
// 如果parent=null,那么啟動(dòng)類加載器就是父親。
this.parent = parent;
initialized = true;
}
// 雙親委派加載的實(shí)現(xiàn)
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// 先檢查該類是否已經(jīng)被裝載過(guò)
Class c = findLoadedClass(name);
if (c == null) {
try {
// 向父加載器委托(加載不到拋ClassNotFoundException)
if (parent != null) {
c = parent.loadClass(name, false);
// 最終到啟動(dòng)類加載器(加載不到拋ClassNotFoundException)
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// 父加載器加載不到,調(diào)用我們自己設(shè)定的findClass(name)進(jìn)行查找
// 對(duì)于API提供的ClassLoader,findClass()是直接拋ClassNotFoundException
c = findClass(name);
}
}
// 是否要解析(解析符號(hào)引用為直接地址引用)
// 一般我們用false。
// 我的理解是使用false的話,程序啟動(dòng)速度應(yīng)該會(huì)有一點(diǎn)點(diǎn)提升,但是第一次執(zhí)行的時(shí)候應(yīng)該會(huì)慢一點(diǎn)點(diǎn)。
// 當(dāng)然,這個(gè)我們?nèi)耸歉杏X(jué)不出來(lái)的。
if (resolve) {
resolveClass(c);
}
return c;
}
=====
from
http://blog.sina.com.cn/s/blog_667ac0360102e8ii.html