1. abstract(抽象) 用法:類修飾符的一種,可以用來修飾類,方法,被修飾的類不能夠?qū)嵗床荒苡胣ew關(guān)鍵字得到對(duì)象),被修飾的方法不能夠?qū)崿F(xiàn)。一個(gè)抽象類中不一定要有抽象方法,但是一個(gè)類里面有抽象方法就一定是抽象類。如果由類要繼承抽象類的話,必須要實(shí)現(xiàn)里面的抽象方法。構(gòu)造方法和靜態(tài)方法不可以修飾為抽象。 例子: public abstract class Animal { public abstract void cry(); public void run(){ System.out.println(“跑的方法……”); } } abstract關(guān)鍵字可以修改類或方法。 abstract類可以擴(kuò)展(增加子類),但不能直接實(shí)例化。 abstract方法不在聲明它的類中實(shí)現(xiàn),但必須在某個(gè)子類中重寫 -示例- public abstract class MyClass{} public abstract StringmyMethod(); 采用abstract方法的類本來就是抽象類,并且必須聲明為abstract。abstract類不能實(shí)例化。 僅當(dāng)abstract類的子類實(shí)現(xiàn)其超類的所有abstract方法時(shí),才能實(shí)例化abstract類的子類。這種類稱為具體類,以區(qū)別于abstract類 。 final 類的方法都不能是 abstract,因?yàn)?final 類不能有子類。 < 1> abstract抽象用在類的聲明中來指明一個(gè)類是不能被實(shí)例化的,但是可以被其他類繼承。一個(gè)抽象類可以使用抽象方法,抽象方法不需要實(shí)現(xiàn),但是需要在子類中被實(shí)現(xiàn)。它的用途是向子類提供通用的信息。抽象類可以包含正常的類包含的任何東西,也就是說,類和實(shí)例變量,以及帶有任何修飾詞的方法。只有抽象類可能有抽象方法。如果一個(gè)不是抽象的類包含一個(gè)抽象方法,那么將會(huì)出現(xiàn)編譯錯(cuò)誤。 a.它顯式的聲明了一個(gè)abstract方法。 b.它從它的直接父類繼承了一個(gè)抽象方法。 <2>如果用戶聲明private,static,和final方法為abstarct,編譯錯(cuò)誤將出現(xiàn)。 不可能重設(shè)一個(gè)private方法,因?yàn)橐粋€(gè)abstarct private永遠(yuǎn)不能被實(shí)現(xiàn)。 static方法總是可用的,因此必須有一個(gè)實(shí)現(xiàn);static abstract將永遠(yuǎn)沒有實(shí)現(xiàn)。 final方法不能被重設(shè),因此不回有final abstract方法的實(shí)現(xiàn)。
2.extends 解釋:擴(kuò)充,擴(kuò)展 extends后面的類,我們稱之為子類。有了繼承關(guān)系之后,我們就說子類擁有父類繼承下來的所有非私有的成員(包括了屬性,方法),但是不包括構(gòu)造方法 。 extends 關(guān)鍵字用在 class 或 interface 聲明中,用于指示所聲明的類或接口是其名稱后跟有 extends 關(guān)鍵字的類或接口的子類。 -注釋-
3.final
解釋:最終的,決定性的 用法:修飾符的一種,它可以用來修飾類,方法,屬性。當(dāng)一個(gè)屬性被修飾成final的之后,這個(gè)屬性變成了常量,它的值必須在定義的時(shí)候初始化,并且后面的代碼不能對(duì)其進(jìn)行修改,它的命名應(yīng)該全部都是大寫。當(dāng)一個(gè)方法被修飾成final的之后,這個(gè)方法在繼承中是不能夠被進(jìn)行覆蓋的。當(dāng)一個(gè)類被修飾成final的之后,這個(gè)類不能再有子類。
final 關(guān)鍵字可以應(yīng)用于類,以指示不能擴(kuò)展該類(不能有子類)。 final 關(guān)鍵字可以應(yīng)用于方法,以指示不能重寫任何子類中的方法。
-示例-
public final class MyFinalClass{ } public class MyClass{ public final String myFinalMethod() { <statements> } }
例子:
public final class Math{ private final float PI = 3.1415926;
public final int abs(int i){ return i>=0?i:-I; } } -注釋- 一個(gè)類不能同時(shí)是 abstract 又是 final。abstract 意味著必須擴(kuò)展類,final 意味著不能擴(kuò)展類。 一個(gè)方法不能同時(shí)是 abstract 又是 final。abstract 意味著必須重寫方法,final 意味著不能重寫方法。 <1>對(duì)于基本類型前加以final修飾,表示被修飾的變量為常數(shù),不可以修改。一個(gè)既是static又是final的字段表示只占據(jù)一段不能改變的存儲(chǔ)空間。
<2>final用于對(duì)象應(yīng)用時(shí),final使應(yīng)用恒定不變。一旦引用被初始化指向一個(gè)對(duì)象,就無法再把它指向另一個(gè)對(duì)象。
<3>final方法:一是把方法鎖定,以防止繼承類修改它的含義,二是確保繼承中使方法行為保持不變,并且不會(huì)被覆蓋。類中所有的private方法都隱式地指定為是final。
<4>final參數(shù):對(duì)于基本類型的變量,這樣做并沒有什么實(shí)際意義,因?yàn)榛绢愋偷淖兞吭谡{(diào)用方法時(shí)是傳值,也就是說你可以在方法中更改這個(gè)參數(shù)變量而不會(huì)影響到調(diào)用語句,然而對(duì)于對(duì)象變量,卻顯得很實(shí)用,以為對(duì)象變量在傳遞時(shí)是傳遞其引用,這樣你在方法中對(duì)對(duì)象變量的修改也會(huì)影響到調(diào)用語句的對(duì)象變量,當(dāng)你在方法中不需要改變作為參數(shù)的變量時(shí),明確使用final進(jìn)行聲明,會(huì)防止你無意的修改而影響到調(diào)用方法。 <5>final類:當(dāng)將某個(gè)類的整體定義為final時(shí),就表明了該類不允許被繼承。
3.finally
解釋:最后,終于,不可更改地 用法:在異常處理機(jī)制當(dāng)中,它的作用就像是人吃飯一樣,必須得做的,不論有異常還是沒有異常都要執(zhí)行的代碼就可以放到finally塊當(dāng)中去。finally塊,必須要配合try塊一起使用,不能單獨(dú)使用,也不能直接和catch塊一起使用。 finally 關(guān)鍵字用來定義始終在 try-catch-finally 語句中執(zhí)行的塊。finally 塊通常包含清理代碼,用在部分執(zhí)行 try 塊后恢復(fù)正常運(yùn)行。
-示例- try{
<可能引發(fā)異常的塊> }
catch (<java.lang.Exception 或子類> e){ <處理異常 e 的代碼>
} finally{
<有異常或無異常情況下都執(zhí)行的語句> } -注釋- 開始和結(jié)束標(biāo)記 { 和 } 是 finally 子句語法的一部分,即使該子句只包含一個(gè)語句,也不能省略這兩個(gè)標(biāo)記。 每個(gè) try 塊都必須至少有一個(gè) catch 或 finally 子句。 如果執(zhí)行 try 塊的任何部分,不論是否出現(xiàn)異常,也不論 try 或 catch 塊是否包含 return、continue 或 break 語句,都一定會(huì)執(zhí)行 finally 塊中的代碼。 如果不出現(xiàn)異常,控件將跳過 try 塊,進(jìn)入 finally 塊。 如果在執(zhí)行 try 塊期間出現(xiàn)異常,并且相應(yīng)的 catch 塊包含 break、continue 或 return 語句,控件將首先穿過 finally 塊,之后再執(zhí)行 break、continue 或 return。
4、implements(接口)
用法:用來讓一個(gè)類實(shí)現(xiàn)一個(gè)接口的關(guān)鍵字,實(shí)現(xiàn)接口的這個(gè)類必須實(shí)現(xiàn)接口里面所有的方法。
implements 關(guān)鍵字在 class 聲明中使用,以指示所聲明的類提供了在 implements 關(guān)鍵字后面的名稱所指定的接口中所聲明的所有方法的實(shí)現(xiàn)。
-示例- public class Truck implements IVehicle{ } -注釋- 在上例中,Truck 類必須提供在 IVehicle 接口中所聲明的所有方法的實(shí)現(xiàn)。 否則,Truck 類將是獨(dú)立的;它可以聲明其他方法和變量,并擴(kuò)展另一個(gè)類。 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。 finally 解釋: 最后,終于,不可更改地
用法: 在異常處理機(jī)制當(dāng)中,它的作用就像是人吃飯一樣,必須得做的,不論有 異常還是沒有異常都要執(zhí)行的代碼就可以放到 finally 塊當(dāng)中去。 finally 塊, 必須要配合 try 塊一起使用, 不能單獨(dú)使用,也不能直接和 catch 塊一起使用。
finally 關(guān)鍵字用來定義始終在
try-catch-finally
語句中執(zhí)行的塊。
finally 塊通常包含清理代碼,用在部分執(zhí)行 try 塊后恢復(fù)正常運(yùn)行。
- 示例 - try{ < 可能引發(fā)異常的塊 > } catch (<Java.lang.Exception 或子類 > e){ < 處理異常 e 的代碼 >
5、instanceof
用法:instanceof 關(guān)鍵字用來確定對(duì)象所屬的類。 -示例-
if (node instanceof TreeNode){ <statements> } -注釋-
在上例中,如果 node 是 TreeNode 類的實(shí)例,或者是 TreeNode 的子類的實(shí)例,則 instanceof 表達(dá)式的值將為 true。 instanceof 通常是用于判斷父類或者接口的引用是否是某個(gè)子類的實(shí)例,例如: class Animal{} class Bird extends Animal {} class Dog extends Animal {} Animal a= new Bird(); System.out.println( a instanceof Bird); System.out.println( a instanceof Dog);
6、interface
解釋:接口,界面
用法:它本質(zhì)上是一個(gè)類,一個(gè)完全抽象的類,里面沒有任何實(shí)現(xiàn)的方法。它不是用來繼承的,是用來實(shí)現(xiàn)的。某個(gè)類如果實(shí)現(xiàn)了接口就必須要實(shí)現(xiàn)接口里面的所有方法。并且接口是不能用來實(shí)例化的,它也是不能通過new關(guān)鍵字獲得對(duì)象。 interface 關(guān)鍵字用來聲明新的 Java 接口,接口是方法的集合。 接口是 Java 語言的一項(xiàng)強(qiáng)大功能。任何類都可聲明它實(shí)現(xiàn)一個(gè)或多個(gè)接口,這意味著它實(shí)現(xiàn)了在這些接口中所定義的所有方法。 -示例- public interface IPolygon{ public float getArea(); public int getNumberOfSides(); public int getCircumference(); } -注釋- 實(shí)現(xiàn)了接口的任何類都必須提供在該接口中的所有方法的實(shí)現(xiàn)。 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。
7、static 解釋:靜態(tài)的
用法:修飾符的一種,能夠用來修飾屬性和方法。需要注意的是被修飾的屬性和方法,不再屬于對(duì)象所有,而是屬于類,意味著,要訪問這些屬性和方法不再通過對(duì)象而是直接用類名來訪問。另外,靜態(tài)的方法不能夠訪問非靜態(tài)屬性,非靜態(tài)的方法能夠訪問靜態(tài)的屬性。 static 關(guān)鍵字可以應(yīng)用于內(nèi)部類(在另一個(gè)類中定義的類)、方法或字段(類的成員變量)。 -示例- public class MyPublicClass{ public final static int MAX_OBJECTS = 100; static int _numObjects = 0; static class MyStaticClass{ } static int getNumObjects(){ } } -注釋- 通常,static 關(guān)鍵字意味著應(yīng)用它的實(shí)體在聲明該實(shí)體的類的任何特定實(shí)例外部可用。 static(內(nèi)部)類可以被其他類實(shí)例化和引用(即使它是頂級(jí)類)。在上面的-示例-中,另一個(gè)類中的代碼可以實(shí)例化 MyStaticClass 類,方法是用包含它的類名來限定其名稱,如 MyClass.MyStaticClass。 static 字段(類的成員變量)在類的所有實(shí)例中只存在一次??梢詮念惖耐獠空{(diào)用 static 方法,而不用首先實(shí)例化該類。這樣的引用始終包括類名作為方法調(diào)用的限定符。在上面的示例中,MyClass 類外部的代碼以 MyClass.getNumObjects() 的形式調(diào)用 getNumObjects() static 方法。 模式: public final static <type> varName = <value>; 通常用于聲明可以在類的外部使用的類常量。在引用這樣的類常量時(shí)需要用類名加以限定。在上面的-示例-中,另一個(gè)類可以用 MyClass.MAX_OBJECTS 形式來引用 MAX_OBJECTS 常量。 1>通常在一個(gè)類中定義一個(gè)方法為static,就是說無須本類的對(duì)象就可以直接調(diào)用。 2>靜態(tài)變量和靜態(tài)方法類似。所有此類實(shí)例共享此靜態(tài)變量,也就是說類裝載時(shí),只分配一塊存儲(chǔ)空間,所有此類的對(duì)象都可以操控此塊存儲(chǔ)空間,當(dāng)然對(duì)于final就另當(dāng)別論了。
3>static定義的變量會(huì)優(yōu)先于任何其他非static變量,不論其出現(xiàn)順序如何。
4>static{}著是用來顯式的靜態(tài)變量初始化,這段代碼只會(huì)初始化一次,且在類被第一次裝載時(shí)。
5>在涉及到繼承的時(shí)候,會(huì)先初始化父類的static變量,然后是子類的。
6>通常一個(gè)普通類不允許聲明為靜態(tài)的,只有一個(gè)內(nèi)部類才可以。這時(shí)這個(gè)聲明為靜態(tài)的內(nèi)部類可以直接作為一個(gè)普通類來使用,而不需要實(shí)例一個(gè)外部類。
8、synchronized
用法:synchronized 關(guān)鍵字可以應(yīng)用于方法或語句塊,并為一次只應(yīng)由一個(gè)線程執(zhí)行的關(guān)鍵代碼段提供保護(hù)。當(dāng)它用來修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同
一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼 -示例- public class MyClass{ public synchronized static String mySyncStaticMethod(){ } public synchronized String mySyncMethod(){ } }
public class MyOtherClass{
Object someObj; public String myMethod(){ <statements> synchronized (someObj){ <statements affecting someObj> }}}
synchronized 關(guān)鍵字可防止代碼的關(guān)鍵代碼段一次被多個(gè)線程執(zhí)行。 如果應(yīng)用于靜態(tài)方法(如上例中的 MySyncStaticMethod),那么,當(dāng)該方法一次由一個(gè)線程執(zhí)行時(shí),整個(gè)類將被鎖定。
如果應(yīng)用于實(shí)例方法(如上例中的 MySyncMethod),那么,當(dāng)該方法一次由一個(gè)線程訪問時(shí),該實(shí)例將被鎖定。 如果應(yīng)用于對(duì)象或數(shù)組,當(dāng)關(guān)聯(lián)的代碼塊一次由一個(gè)線程執(zhí)行時(shí),對(duì)象或數(shù)組將被鎖定。 synchronized 關(guān)鍵字,它包括兩種用法:synchronized 方法和 synchronized 塊。 1. synchronized 方法:通過在方法聲明中加入 synchronized關(guān)鍵字來聲明 synchronized 方法。 如: public synchronized void accessVal(int newVal);
synchronized 方法控制對(duì)類成員變量的訪問:每個(gè)類實(shí)例對(duì)應(yīng)一把鎖,每個(gè) synchronized 方法都必須獲得調(diào)用該方法的類實(shí)例的鎖方能執(zhí)行,否則所屬線程阻塞,方法一旦執(zhí)行,就獨(dú)占該鎖,直到從該方法返回時(shí)才將鎖釋放,此后被阻塞的線程方能獲得該鎖,重新進(jìn)入可執(zhí)行狀態(tài)。這種機(jī)制確保了同一時(shí)刻對(duì)于每一個(gè)類實(shí)例,其所有聲明為 synchronized 的成員函數(shù)中至多只有一個(gè)處于可執(zhí)行狀態(tài)(因?yàn)橹炼嘀挥幸粋€(gè)能夠獲得該類實(shí)例對(duì)應(yīng)的鎖),從而有效避免了類成員變量的訪問沖突(只要所有可能訪問類成員變量的方法均被聲明為
synchronized)。
在 Java 中,不光是類實(shí)例,每一個(gè)類也對(duì)應(yīng)一把鎖,這樣我們也可將類的靜態(tài)成員函數(shù)聲明為 synchronized ,以控制其對(duì)類的靜態(tài)成員變量的訪問。
synchronized 方法的缺陷:若將一個(gè)大的方法聲明為synchronized 將會(huì)大大影響效率,典型地,若將線程類的方法 run() 聲明為synchronized ,由于在線程的整個(gè)生命期內(nèi)它一直在運(yùn)行,因此將導(dǎo)致它對(duì)本類任何 synchronized 方法的調(diào)用都永遠(yuǎn)不會(huì)成功。當(dāng)然我們可以通過將訪問類成員變
量的代碼放到專門的方法中, 將其聲明為 synchronized , 并在主方法中調(diào)用來 解決這一問題, 但是 Java 為我們提供了更好的解決辦法, 那就是 synchronized 塊。 synchronized(syncObject) { //允許訪問控制的代碼 } synchronized 塊是這樣一個(gè)代碼塊,其中的代碼必須獲得對(duì)象 syncObject (如前所述,可以是類實(shí)例或類)的鎖方能執(zhí)行,具體機(jī)制同前所述。由于可以針對(duì)任意代碼塊,且可任意指定上鎖的對(duì)象,故靈活性較高。 對(duì)synchronized(this)的一些理解 1)、當(dāng)兩個(gè)并發(fā)線程訪問同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。package ths;
public class Thread1 implements Runnable { public void run() { synchronized(this) {
for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); } } } public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");ta.start();
tb.start(); } }
2)、當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
3)、然而,當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
4)、第三個(gè)例子同樣適用其它同步代碼塊。也就是說,當(dāng)一個(gè)線程訪問object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問都被暫時(shí)阻塞。
9、transient
用法:transient 關(guān)鍵字可以應(yīng)用于類的成員變量,以便指出該成員變量不應(yīng) 在包含它的類實(shí)例已序列化時(shí)被序列化。 -示例- public class MyClass{ private transient String password; } java語言的關(guān)鍵字,變量修飾符,如果用transient聲明一個(gè)實(shí)例變量,當(dāng)對(duì)象存儲(chǔ)時(shí),它的值不需要維持。 Java的serialization提供了一種持久化對(duì)象實(shí)例的機(jī)制。當(dāng)持久化對(duì)象時(shí),可能有一個(gè)特殊的對(duì)象數(shù)據(jù)成員,我們不想 用serialization機(jī)制來保存它。為了在一個(gè)特定對(duì)象的一個(gè)域上關(guān)閉serialization,可以在這個(gè)域前加上關(guān)鍵字transient。 transient是Java語言的關(guān)鍵字,用來表示一個(gè)域不是該對(duì)象串行化的一部分。當(dāng)一個(gè)對(duì)象被串行化的時(shí)候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進(jìn)去的。
10、volatile
用法:volatile 關(guān)鍵字用于表示可以被多個(gè)線程異步修改的成員變量。 注意:volatile 關(guān)鍵字在許多 Java 虛擬機(jī)中都沒有實(shí)現(xiàn)。 -示例- public class MyClass{ volatile int sharedValue; } -注釋- volatile 的目標(biāo)用途是為了確保所有線程所看到的指定變量的值都是相同的。 Volatile修飾的成員變量在每次被線程訪問時(shí),都強(qiáng)迫從主內(nèi)存中重讀該成員變量的值。而且,當(dāng)成員變量發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫到主內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。Java語言規(guī)范中指出:為了獲得最佳速度,允許線程保存共享成員變量的私有拷貝,而且只當(dāng)線程進(jìn)入或者離開同步代碼塊時(shí)才與共享成員變量的原始值對(duì)比。 這樣當(dāng)多個(gè)線程同時(shí)與某個(gè)對(duì)象交互時(shí),就必須要注意到要讓線程及時(shí)的得到共享成員變量的變化。 而volatile關(guān)鍵字就是提示VM:對(duì)于這個(gè)成員變量不能保存它的私有拷貝,而應(yīng)直接與共享成員變量交互。 使用建議:在兩個(gè)或者更多的線程訪問的成員變量上使用volatile。當(dāng)要訪問的變量已在synchronized代碼塊中,或者為常量時(shí),不必使用。 由于使用volatile屏蔽掉了VM中必要的代碼優(yōu)化,所以在效率上比較低,因此一定在必要時(shí)才使用此關(guān)鍵字。 11、finally 解釋:最后,終于,不可更改地 用法: 在異常處理機(jī)制當(dāng)中,它的作用就像是人吃飯一樣,必須得做的,不論有 異常還是沒有異常都要執(zhí)行的代碼就可以放到 finally 塊當(dāng)中去。 finally 塊, 必須要配合 try 塊一起使用, 不能單獨(dú)使用,也不能直接和 catch 塊一起使用。
finally 關(guān)鍵字用來定義始終在
try-catch-finally
語句中執(zhí)行的塊。
finally 塊通常包含清理代碼,用在部分執(zhí)行 try 塊后恢復(fù)正常運(yùn)行。
- 示例 - try{ < 可能引發(fā)異常的塊 > } catch (<java.lang.Exception 或子類 > e){ < 處理異常 e 的代碼 > finally 解釋: 最后,終于,不可更改地
用法: 在異常處理機(jī)制當(dāng)中,它的作用就像是人吃飯一樣,必須得做的,不論有 異常還是沒有異常都要執(zhí)行的代碼就可以放到 finally 塊當(dāng)中去。 finally 塊, 必須要配合 try 塊一起使用, 不能單獨(dú)使用,也不能直接和 catch 塊一起使用。
finally 關(guān)鍵字用來定義始終在
try-catch-finally
語句中執(zhí)行的塊。
finally 塊通常包含清理代碼,用在部分執(zhí)行 try 塊后恢復(fù)正常運(yùn)行。
- 示例 - try{ < 可能引發(fā)異常的塊 > } catch (<java.lang.Exception 或子類 > e){ < 處理異常 e 的代碼 > |
|