Java的abstract,static ,final關鍵字的用法__Java

來源:互聯網
上載者:User
關鍵概念:抽象類別,抽象方法,靜態類,靜態內部類,靜態方法,靜態變數,常量,全域常量。
一、abstract的用法,修飾符,可以修飾類和方法  1、abstract修飾類,會使這個類成為一個抽象類別(詳細的知識見java抽象類別和抽象方法博文)    這個類將不能產生對象執行個體,但可以做為物件變數聲明的類型,也就是編譯時間類型,   抽象類別就像當於一類的半成品,需要子類繼承並覆蓋其中的抽象方法。
2,abstract修飾方法,會使這個方法變成抽象方法,   也就是只有聲明(定義)而沒有實現,實現部分以";"代替。需要子類繼承實現(覆蓋)。
3、 有抽象方法的類一定是抽象類別。但是抽象類別中不一定都是抽象方法,也可以全是具體方法。 abstract修飾符在修飾類時必須放在類名前。 abstract修飾方法就是要求其子類覆蓋(實現)這個方法。調用時可以以多態方式調用子類覆蓋(實現)後的方法,也就是說抽象方法必須在其
4、 子類中實現,除非子類本身也是抽象類別。 父類是抽象類別,其中有抽象方法,那麼子類繼承父類,並把父類中的所有抽象方法都實現(覆蓋)了,子類才有建立對象的執行個體的能力, 否則子類也必須是抽象類別。抽象類別中可以有構造方法,是子類在構造子類對象時需要調用的父類(抽象類別)的構造方法。
二、static 的用法,被修飾的方法稱為靜態方法,被修飾的變數稱為靜態變數(詳細見靜態變數和靜態方法的博文)
關於靜態變數和靜態方法代碼塊,也就是JVM在載入靜態變數和方法是會載入帶記憶體中,作為公用的變數和方法, 也就是在對象建立之前就已經在記憶體中建立好對應的變數和方法。
1. 靜態方法  public static void prt(String s) {        System.out.println(s);     } 通常,在一個類中定義一個方法為static,那就是說,無需本類的對象即可調用此方法    聲明為static的方法有以下幾條限制: · 它們僅能調用其他的static 方法。 · 它們只能訪問static資料。 · 它們不能以任何方式引用this 或super。
調用一個靜態方法就是“類名.方法名”,靜態方法的使用很簡單如上所示。一般來說,靜態方法常常為應用程式中的其它類提供一些 工具 + 生產力所用,在Java的類庫中大量的靜態方法正是出於此目的而定義的。 靜態方法通常作為工具類或者工具方法中使用。
2、靜態變數  static int c = 0; 聲明為static的變數實質上就是全域變數。當聲明一個對象時,並不產生static變數的拷貝,而是該類所有的執行個體變數共用同一個static變數。 靜態變數與靜態方法類似。所有此類執行個體共用此靜態變數,也就是說在類裝載時,只分配一Block Storage空間,所有此類的對象都可以操控此Block Storage 空間,當然對於final則另當別論了。
靜態方法代碼塊:一般可以作為一個對象的初始化的方法。 static{   String driverClass="..";   String url="";   String username="";   String password=""; } 以上代碼就能初始化資料庫連接
3、靜態內部類,通常一個公用類不能設定為靜態,只能是內部類設定為靜態。 class OuterCls {     public static class InnerCls {        InnerCls() {            System.out.println("InnerCls");        }     } } 使用靜態內部類: public class StaticCls {     public static void main(String[] args) {        OuterCls.InnerCls oi = new OuterCls.InnerCls();     } }
4.static和final一塊用表示什麼 static final用來修飾成員變數和成員方法,可簡單理解為“全域常量”。 對於變數,表示一旦給值就不可修改,並且通過類名可以訪問。 對於方法,表示不可覆蓋,並且可以通過類名直接存取。
5、補充總結說明: static表示“全域”或者“靜態”的意思,用來修飾成員變數和成員方法,也可以形成靜態static代碼塊, 但是Java語言中沒有全域變數的概念。
 被static修飾的成員變數和成員方法獨立於該類的任何對象。也就是說,它不依賴類特定的執行個體,被類的所有執行個體共用。 只要這個類被載入,Java虛擬機器就能根據類名在運行時資料區的方法區內定找到他們。因此,static對象可以在它的任何對象建立之前訪問, 無需引用任何對象。
 用public修飾的static成員變數和成員方法本質是全域變數和全域方法,當聲明它類的對象時,不產生static變數的副本, 而是類的所有執行個體共用同一個static變數。
 static 變數前可以有private修飾,表示這個變數可以在類的靜態代碼塊中,或者類的其他靜態成員方法中使用(當然也可以在非靜態成員 方法中使用--廢話),但是不能在其他類中通過類名來直接引用,這一點很重要。實際上你需要搞明白,private是存取權限限定, static表示不要執行個體化就可以使用,這樣就容易理解多了。static前面加上其它存取權限關鍵字的效果也以此類推。
 static修飾的成員變數和成員方法習慣上稱為靜態變數和靜態方法,可以直接通過類名來訪問,訪問文法為: 類名.靜態方法名(參數列表...) 類名.靜態變數名
 用static修飾的代碼塊表示靜態代碼塊,當Java虛擬機器(JVM)載入類時,就會執行該代碼塊(用處非常大,呵呵)。
static變數  按照是否靜態對類成員變數進行分類可分兩種:一種是被static修飾的變數,叫靜態變數或類變數;另一種是沒有被static修飾的變數,   叫執行個體變數。兩者的區別是:  對於靜態變數在記憶體中只有一個拷貝(節省記憶體),JVM只為靜態分配一次記憶體,在載入類的過程中完成靜態變數的記憶體配置,   可用類名直接存取(方便),當然也可以通過對象來訪問(但是這是不推薦的)。  對於執行個體變數,沒建立一個執行個體,就會為執行個體變數分配一次記憶體,執行個體變數可以在記憶體中有多個拷貝,互不影響(靈活)。
static方法  靜態方法可以直接通過類名調用,任何的執行個體也都可以調用,因此靜態方法中不能用this和super關鍵字,不能直接存取所屬類的 執行個體變數和執行個體方法 (就是不帶static的成員變數和成員成員方法),只能訪問所屬類的靜態成員變數和成員方法。 因為執行個體成員與特定的對象關聯。
因為static方法獨立於任何執行個體,因此static方法必須被實現,而不能是抽象的abstract。
三、final關鍵字的使用
1. 修飾基礎資料成員的一般稱為常量,必須在聲明的時候設定值。也成為編譯時間常數。 這是final的主要用途,其含義相當於C/C++的const,即該成員被修飾為常量,意味著不可修改。如java.lang.Math類中 的PI和E是final成員,其值為3.141592653589793和2.718281828459045。
2. 修飾類或對象的引用的final,一般使用的比較少。 在Java中,我們無法讓對象被修飾為final,而只能修飾對象的引用,這意味著即使你寫public final A a = new A();  事實上a指向的對象的資料依然可以被修改,不能修改的是a本身的引用值,即你不能再對a進行重賦值。同樣的情況出現 在數組中,比如public final int[] a = {1, 2, 3, 4, 5},事實上a中的數值是可修改的,即可以寫  a[0] = 3。據目前瞭解,java中數組內的資料是無法修飾為不可修改的,而C/C++可以。
3.修飾方法的類的子類只能使用不能修改或者叫重寫。   修飾方法的final和C/C++中修飾成員對象的const大不相同。首先,修飾方法的final含義不是“不可修改”,而是指該方法  不可被繼承成員重新定義。(注意,這裡所說的不能被重新定義,並不是指子類一定不能定義同名方法,如果父類的方法是 私人類型,子類是允許定義該方法的,這裡指的不能重新定義是指不能通過改寫方法來使得方法重寫的多態性得以實現, 如不希望A a = new B(); a.f();這樣的重寫方法情況出現)
此外,當一個方法被修飾為final方法時,意味著編譯器可能將該方法用內聯(inline)方式載入,所謂內聯方式,是指編譯器不用 像平常調用函數那樣的方式來調用方法,而是直接將方法內的代碼通過一定的修改後copy到原代碼中(將方法主體直接插入到調用處, 而不是進行方法調用)。這樣可以讓代碼執行的更快(因為省略了調用函數的開銷),比如在int[] arr = new int[3]調用arr.length()等。 另一方面,私人方法也被編譯器隱式修飾為final,這意味著private final void f()和private void f()並無區別。
4.修飾類的final的類不能被繼承,例如String類。 當一個類被修飾為final時,它的含義很明確,就是不允許該類被繼承,也就是說,該類“絕後”了,任何繼承它的操作都會以 編譯錯誤告終。這也凸顯出Java用final而不用const作為標識符的理由。(成員變數可以不是final,成員方法直接是final的)
關於final還有比較深入的知識,這裡不做太深入的瞭解。
五、Java語言的關鍵字synchronized用法,主要是在多線程中使用。   當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多隻有一個線程執行該段代碼。
1、當兩個並發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。 另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。
2、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的 非synchronized(this)同步代碼塊。
3、尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它 synchronized(this)同步代碼塊的訪問將被阻塞。
4、第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時, 它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。 5、以上規則對其它對象鎖同樣適用.
總結補充: synchronized關鍵字的範圍有二種: 1)是某個對象執行個體內,synchronized aMethod(){}可以防止多個線程同時訪問這個對象的synchronized方法 (如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,其它線程不能 同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象執行個體的synchronized方法是不相干擾的。 也就是說,其它線程照樣可以同時訪問相同類的另一個對象執行個體中的synchronized方法;
2)是某個類的範圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的 synchronized static 方法。它可以對類的所有對象執行個體起作用。 2、除了方法前用synchronized關鍵字,synchronized關鍵字還可以用於方法中的某個區塊中,表示只對這個區塊 的資源實行互斥訪問。用法是: synchronized(this){/*區塊*/},它的範圍是當前對象;
3、synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中並不自動是 synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.