from:http://www.blogjava.net/realsmy/archive/2007/04/10/109256.html
from:http://www.wljcz.com/html/j2se/javajc/2010/0408/3262.html
from:http://www.javaeye.com/topic/72543
from:http://www.dingkao.com/a/100627/50164/
from:http://blog.pfan.cn/sword2008/13772.html
from:http://www.cnblogs.com/wjun530/archive/2007/09/15/893802.html
不同于方法,構造器不能是abstract, static, final, native, strictfp, 或者synchronized的.
1.構造器不是通過繼承得到的,所以沒有必要把它聲明為final的。
2.同理,一個抽象的構造器將永遠不會被實現。(所以也不能聲明為abstract的)
3.構造器總是關聯一個對象而被調用,所以把它聲明為static是沒有意義的。
4.沒有實際的需要把構造器定義成同步的,因為它將會在構造的時候鎖住該對象,直到所有的構造器完成它們的工作,這個構造的過程對其它線程來說,通常是不可訪問的。 (synchronized)
5.本地化的方法情況特別復雜,所以JVM調用起來非常麻煩,需要考慮很多種情況,沒有native關鍵字的情況下,JVM實現起來比較容易。
注:strictfp、native、transient、volatile用法
1)strictfp:strictfp的意思是FP-strict,也就是說精確浮點的意思。
在Java虛擬機進行浮點運算時,如果沒有指定strictfp關鍵字時, Java的編譯器以及運行環境在對浮點運算的表達式是采取一種近似于我行我素的行為來完成這些操作,以致于得到的結果往往無法令你滿意。而一旦使用了 strictfp來聲明一個類、接口或者方法時,那么所聲明的范圍內Java的編譯器以及運行環境會完全依照浮點規范IEEE-754來執行。因此如果你想讓你的浮點運算更加精確,而且不會因為不同的硬件平臺所執行的結果不一致的話,那就請用關鍵字strictfp。
你可以將一個類、接口以及方法聲明為strictfp,但是不允許對接口中的方法以及構造函數聲明strictfp關鍵字。例如:
一、錯誤的使用方法
interface A {
strictfp void f(); //接口中的方法
}
public class FpDemo2 {
strictfp FpDemo2() {} // 構造函數
}
二、合法的使用關鍵字strictfp
strictfp interface A {} //接口
public strictfp class FpDemo1 { //類
strictfp void f() {} //方法
}
2)native:native是方法修飾符。Native方法是由另外一種語言(如c/c++,FORTRAN,匯編)實現的本地方法。有時java應用需要與java外面的環境交互。這是本地方法存在的主要原因。
因為在外部實現了方法,所以在java代碼中,就不需要聲明了,有點類似于接口方法。Native可以和其他一些修飾符連用,但是abstract方法和Interface方法不能用native來修飾。
在定義一個native method時,并不提供實現體(有些像定義一個java interface),因為其實現體是由非java語言在外面實現的。例:
public class IHaveNatives
{
native public void Native1( int x ) ;
native static public long Native2() ;
native synchronized private float Native3( Object o ) ;
native void Native4( int[] ary ) throws Exception ;
}
這些方法的聲明描述了一些非java代碼在這些java代碼里看起來像什么樣子(view).
不能用abstract的原因:這是合理的,因為native暗示這些方法是有實現體的,只不過這些實現體是非java的,但是abstract卻顯然的指明這些方法無實現體。
native與其它java標識符連用時,其意義同非Native Method并無差別,比如native static表明這個方法可以在不產生類的實例時直接調用,這非常方便,比如當你想用一個native method去調用一個C的類庫時。上面的第三個方法用到了native synchronized,JVM在進入這個方法的實現體之前會執行同步鎖機制。
3)transient:變量修飾符(只能修飾字段)。
標記為transient的變量,在對象存儲時,這些變量狀態不會被持久化。當對象序列化地保存在存儲器上時,不希望有些字段數據被保存,為了保證安全性,可以把這些字段聲明為transient。
4)volatile:volatile修飾變量。在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。而且,當成員變量發生變化時,強迫線程將變化值回寫到共享內存。這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值。
volatile與synchronized的區別:
1.volatile本質是在告訴jvm當前變量在寄存器(工作內存)中的值是不確定的,需要從主存中讀取;synchronized則是鎖定當前變量,只有當前線程可以訪問該變量,其他線程被阻塞住。
2.volatile僅能使用在變量級別;synchronized則可以使用在變量、方法、和類級別的
3.volatile僅能實現變量的修改可見性,不能保證原子性;而synchronized則可以保證變量的修改可見性和原子性
4.volatile不會造成線程的阻塞;synchronized可能會造成線程的阻塞。
5.volatile標記的變量不會被編譯器優化;synchronized標記的變量可以被編譯器優化
5)static:
1>靜態方法:通常,在一個類中定義一個方法為static,那就是說,用類名而無需本類的對象即可調用此方法。靜態方法常常為應用程序中的其它類提供一些實用工具所用。
2>靜態變量:靜態變量與靜態方法類似。所有此類實例共享此靜態變量,也就是說在類裝載時,只分配一塊存儲空間,所有此類的對象都可以操控此塊存儲空間,當然對于final則另當別論了。
3>static定義的變量會優先于任何其它非static變量,不論其出現的順序如何。
在static{}內的代碼,是用來進行顯式的靜態變量初始化,這段代碼只會初始化一次,且在類被第一次裝載時。在涉及到繼承的時候,會先初始化父類的static變量,然后是子類的,依次類推。
4>通常一個普通類不允許聲明為靜態的,只有一個內部類才可以。這時這個聲明為靜態的內部類可以直接作為一個普通類來使用,而不需實例一個外部類。但是,不能從靜態內部類的對象中訪問非靜態的外圍類對象和方法(可訪問外部靜態的對象、方法)。例如:
public class StaticCls{
public static void main(String[] args){
OuterCls.InnerCls oi=new OuterCls.InnerCls();
}
}
class OuterCls{
public static class InnerCls{
InnerCls(){
System.out.println("InnerCls");
}
}
}
PS:非static內部類,初始化方法:
outerObject=new outerClass(Constructor Parameters);
outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);
注意在創建非靜態內部類對象時,一定要先創建起相應的外部類對象。至于原因,非靜態內部類對象有著指向其外部類對象的引用,一個內部類對象可以訪問創建它的外部類對象的內容,甚至包括私有變量!
static與非static內部類區別:1、靜態內部類沒有了指向外部的引用。2、在任何非靜態內部類中,都不能有靜態數據,靜態方法或者又一個靜態內部類(內部類的嵌套可以不止一層)。不過靜態內部類中卻可以擁有這一切。
6)final
final變量:
在類中定義變量時,在其前面加上final關鍵字,那便是說,這個變量一旦被初始化便不可改變,這里不可改變的意思對基本類型來說是其值不可變,而對于對象變量來說其引用不可再變。
其初始化可以在兩個地方,一是其定義處,也就是說在final變量定義時直接給其賦值,二是在構造函數中。這兩個地方只能選其一,要么在定義時給值,要么在構造函數中給值,不能同時既在定義時給了值,又在構造函數中給另外的值。
還有一種用法是定義方法中的參數為final,對于基本類型的變量,這樣做并沒有什么實際意義,因為基本類型的變量在調用方法時是傳值的,也就是說你可以在方法中更改這個參數變量而不會影響到調用語句,然而對于對象變量,卻顯得很實用,因為對象變量在傳遞時是傳遞其引用,這樣你在方法中對對象變量的修改也會影響到調用語句中的對象變量,當你在方法中不需要改變作為參數的對象變量時,明確使用final進行聲明,會防止你無意的修改而影響到調用方法。
final方法:
將方法聲明為final,那就說明你已經知道這個方法提供的功能已經滿足你要求,不需要進行擴展,并且也不允許任何從此類繼承的類來覆寫這個方法,但是繼承仍然可以繼承這個方法,也就是說可以直接使用。編譯器在遇到調用final方法時候會轉入內嵌inline機制,它會使你在調用final方法時,直接將方法主體插入到調用處,而不是進行例行的方法調用,例如保存斷點,壓棧等,這樣可能會使你的程序效率有所提高,然而當你的方法主體非常龐大時,或你在多處調用此方法,那么你的調用主體代碼便會迅速膨脹,可能反而會影響效率,所以你要慎用final進行方法定義。
final類:
當你將final用于類身上時,你就需要仔細考慮,因為一個final類是無法被任何人繼承的,那也就意味著此類在一個繼承樹中是一個葉子類,并且此類的設計已被認為很完美而不需要進行修改或擴展。對于final類中的成員,你可以定義其為final,也可以不是final。而對于方法,由于所屬類為final的關系,自然也就成了final型的。你也可以明確的給final類中的方法加上一個final,但這顯然沒有意義。
7)static和final一塊用表示什么
static final用來修飾成員變量和成員方法,可簡單理解為“全局常量”!
對于變量,表示一旦給值就不可修改,并且通過類名可以訪問; 對于方法,表示不可覆蓋,并且可以通過類名直接訪問。