實際開發(fā)中,為了對變量進行封裝揽思,提高方法和變量訪問安全性等袜腥,就要用到各種修飾符的功能。
Java修飾符分兩種
1钉汗、訪問修飾符
public 公用的瞧挤,對所有類可見,可用來修飾類儡湾,方法和變量特恬,構(gòu)造函數(shù)
protected 受保護的,同包或子類可見徐钠,可用來修飾方法和變量癌刽,構(gòu)造函數(shù)
defualt 默認的,不帶修飾符尝丐,僅對同包可見显拜,可用來修飾類,方法和變量爹袁,構(gòu)造函數(shù)
2、非訪問修飾符
static
靜態(tài)修飾符盹兢,可以用于修飾類邻梆,方法,和變量
修飾類時绎秒,作為靜態(tài)內(nèi)部類使用浦妄。
修飾方法和變量時,程序運行時就加載见芹,不用new 一個對象剂娄,就能直接調(diào)用,常用final一起用
例子:
/*定義一個靜態(tài)內(nèi)部類,里面包含靜態(tài)方法和靜態(tài)變量*/ public static final class FinalClass3Static { public static String string = "這是FinalClass3的的靜態(tài)內(nèi)部類FinalClass3Static的final3Method()"; public static void final3Method() { System.out.println(string); } }
final
可以用于修飾類玄呛,方法阅懦,還有變量
當(dāng)用于修飾類時,該類不能被繼承把鉴,故沒有子類故黑,此final類中的方法默認是final的,反正不能被繼承庭砍,那也是沒辦法被重寫的了场晶。
當(dāng)用于修飾方法時,final方法不能被子類重寫怠缸,但可以被直接調(diào)用诗轻,也可以被重載
當(dāng)用于修飾變量時,常與static合用揭北,表示常量扳炬,只能被賦值一次,賦值后值不能再被改變搔体。
案例1:
public final abstract class AbstractClass{}
這樣寫是錯的恨樟,final不能和abstract共用,因為抽象類的誕生就是為了讓子類來繼承它 再實現(xiàn)方法的,而加了final之后就無法被繼承了疚俱,這樣定義這類沒意義了劝术。
案例2:
public final class AbstractClass{} public class Class2 extends AbstractClass{}
這樣寫是錯的,因為final類無法被繼承
案例3:
public class FinalClass{ public final void finalMethod1(){ System.out.println("這是FinalClass下的finalMethod1()方法"); } } public class FinalClass2 extends FinalClass { /*final方法只能在子類直接調(diào)用呆奕,而無法進行重寫*/ @Override public final void finalMethod1() { System.out.println("這是TestFinal2n下的finalMethod1()方法"); } /*隨不能重寫养晋,但可以重載*/ public static final void finalMethod1(String string){ System.out.println("這是FinalClass2下的finalMethod1()方法"+string); } }
這樣寫是錯的,因為finalMethod1()是final方法梁钾,繼承的子類只能直接調(diào)用該方法绳泉,但不能重寫final方法。 ps:可以重載該方法
案例4:
public static final String MY_FINAL_STRING ="myFinalString"; MY_FINAL_STRING = “ttt”;
這樣寫也是錯的姆泻,無法為final變量重新賦值
abstract
可以用來修飾類和方法零酪,abstract不能和final或static公用。案例中會解釋
用于修飾類時拇勃,抽象類可以包含抽象方法蛾娶,也可以不包含抽象方法,但如果是包含抽象方法潜秋,則一定要變成抽象類蛔琅。
當(dāng)子類繼承某抽象類時,必須實現(xiàn)其中的抽象方法峻呛。
用于修飾方法時罗售,該方法只能有方法聲明,不能包含方法體钩述,需要被子類覆蓋重寫該方法寨躁,才能使用。
不能用來修飾變量牙勘。
案例1:
public final abstract void AbstractMethod(){ System.out.println("這是一個抽象方法"); }
這是錯的职恳,抽象方法不能再用final來修飾所禀,因為抽象方法只有繼承了它的子類才能調(diào)用的(而加了final的類不能被繼承),也不能有方法體
public static abstract void AbstractMethod(){
System.out.println("這是一個抽象方法"); }
這也是錯的放钦,因為static表示靜態(tài)色徘,而abstract是動態(tài)的要運行時才能確定下來
案例2:
public abstract class AbstractClass {}
AbstractClass abstractClass = new AbstractClass();
這是錯的,抽象類無法被實例化操禀,不能new褂策,但可以用匿名內(nèi)部類的方法來實現(xiàn),如下面
AbstractClass abstractClass = new AbstractClass() { @Override public void AbstractMethod2() { } @Override void AbstractMethod3() { } };
synchronized
當(dāng)它用來修飾一個方法或者一個代碼塊的時候颓屑,能夠保證在同一時刻最多只有一個線程執(zhí)行該段代碼斤寂。 一、當(dāng)兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時揪惦,一個時間內(nèi)只能有一個線程得到執(zhí)行遍搞。另一個線程必須等待當(dāng)前線程執(zhí)行完這個代碼塊以后才能執(zhí)行該代碼塊。
二器腋、然而尾抑,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊蒂培。
三再愈、尤其關(guān)鍵的是,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時护戳,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞翎冲。
四、第三個例子同樣適用其它同步代碼塊媳荒。也就是說抗悍,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖钳枕。結(jié)果缴渊,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
transient
在java中鱼炒,如果一個對象實現(xiàn)了serializable接口衔沼,那么這對象的方法和屬性就可以被序列化,但實際開發(fā)中昔瞧,我們有時方法或?qū)傩圆⒉幌胨恍蛄谢敢希藭r就要用到transient關(guān)鍵字,添加了此關(guān)鍵字的屬性自晰,在實現(xiàn)serializable接口凝化,不會被序列化 transient關(guān)鍵字只能修飾變量,而不能修飾方法和類
volatile
用來確保將變量的更新操作通知到其他線程,保證了新值能立即同步到主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新. 當(dāng)把變量聲明為volatile類型后,編譯器與運行時都會注意到這個變量是共享的 存在線程安全問題酬荞。
Demo工程下載地址
http://download.csdn.net/detail/forgot2015/9732243
參考文章
http://lavasoft.blog.51cto.com/62575/18771/ http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html http://www.cnblogs.com/lanxuezaipiao/p/3369962.html http://www.ibm.com/developerworks/cn/java/j-jtp06197.html