<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    瘋狂

    STANDING ON THE SHOULDERS OF GIANTS
    posts - 481, comments - 486, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    java 修飾符

    Posted on 2009-11-02 14:31 瘋狂 閱讀(905) 評論(0)  編輯  收藏

    Java語言定義了public、protected、private、abstract、static和final這6常用修飾
    詞外還定義了5個不太常用的修飾詞,下面是對這11個Java修飾詞的介紹:
    1.public
    使用對象:類、接口、成員
    介紹:無論它所處在的包定義在哪,該類(接口、成員)都是可訪問的
    2.private
    使用對象:成員
    介紹:成員只可以在定義它的類中被訪問
    3.static
    使用對象:類、方法、字段、初始化函數
    介紹:成名為static的內部類是一個頂級類,它和包含類的成員是不相關的。靜態方法
    是類方法,
    是被指向到所屬的類而不是類的實例。靜態字段是類字段,無論該字段所在的類創建了
    多少實例,該字
    段只存在一個實例被指向到所屬的類而不是類的實例。初始化函數是在裝載類時執行
    的,而不是在創建
    實例時執行的。
    4.final
    使用對象:類、方法、字段、變量
    介紹:被定義成final的類不允許出現子類,不能被覆蓋(不應用于動態查詢),字段值
    不允許被
    修改。
    5.abstract
    使用對象:類、接口、方法
    介紹:類中包括沒有實現的方法,不能被實例化。如果是一個abstract方法,則方法體
    為空,該方
    法的實現在子類中被定義,并且包含一個abstract方法的類必須是一個abstract類
    6.protected
    使用對象:成員
    介紹:成員只能在定義它的包中被訪問,如果在其他包中被訪問,則實現這個方法的類
    必須是該成
    員所屬類的子類。
    7.native
    使用對象:成員
    介紹:與操作平臺相關,定義時并不定義其方法,方法的實現被一個外部的庫實現。
    8.strictfp
    使用對象:類、方法
    介紹:strictfp修飾的類中所有的方法都隱藏了strictfp修飾詞,方法執行的所有浮點
    計算遵守
    IEEE 754標準,所有取值包括中間的結果都必須表示為float或double類型,而不能利用
    由本地平臺浮
    點格式或硬件提供的額外精度或表示范圍。
    9.synchronized
    使用對象:方法
    介紹:對于一個靜態的方法,在執行之前jvm把它所在的類鎖定;對于一個非靜態類的方
    法,執行
    前把某個特定對象實例鎖定。
    10.volatile
    使用對象:字段
    介紹:因為異步線程可以訪問字段,所以有些優化操作是一定不能作用在字段上的。

    volatile修飾變量。在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。而且,當成員變量發生變化時,強迫線程將變化值回寫到共享內存。這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值。
    看看Java Language Specification中的例子。
    條件:一個線程不停的調用方法one(),一個線程不停的調用方法two()。我測試過多次,這種情況好像一直沒有出現。

    代碼
    class Test {   
         static int i = 0, j = 0;   
         static void one() { i++; j++; }   
         static void two() {   
             System.out.println("i=" + i + " j=" + j);   
         }   
    }   

    結果偶爾會出現j大于i的情況,因為方法沒有同步,所以會出現i和j可能不是一次更新。一種防止這種情況發生的辦法就是聲明兩個方法為synchronized 的。

    代碼
    class Test {   
         static int i = 0, j = 0;   
         static synchronized void one() { i++; j++; }   
         static synchronized void two() {   
             System.out.println("i=" + i + " j=" + j);   
         }   
    }   

    這樣可以防止兩個方法同時被執行,還可以保證j和i被同時更新,這樣一來i和j的值一直是一樣的。
    另外一種途徑就是把i和j聲明為volatile。

    代碼
    class Test {   
         static volatile int i = 0, j = 0;   
         static void one() { i++; j++; }   
         static void two() {   
             System.out.println("i=" + i + " j=" + j);   
         }   
    }  

    volatile有時
    可以代替synchronized。
    11.transient
    使用對象:字段
    介紹:字段不是對象持久狀態的一部分,不應該把字段和對象一起串起。  

    transient是一個變量修飾符,標記為transient的變量,在對一個對象進行序列化時,這些變量狀態不會被序列化。

    例如,假設某個類的成員變量是transient,那么當通過ObjectOutputStream把這個類的某個實例保存到磁盤上時,實際上transient變量的值是不會保存的。

    當對象序列化的保存在存儲器上時,不希望有些字段數據被保存,為了保證安全性,可以把這些字段聲明為transient。

    要更明白,可以看一些序列化的內容。

    -------------------------------------------------------

     

    Java語言規定,在同一個包中的class,如果沒有修飾符,默認為Package權限,包內的class都可以訪問。但是這還不夠準確。確切的說,只有由同一個ClassLoader裝載的class才具有以上的Package權限。
    [關鍵字] JavaClassLoader Package

      為了深入了解Java的ClassLoader機制,我們先來做以下實驗:

      package java.lang;

      public class Test {

      public static void main(String[] args) {

      char[] c = "1234567890".toCharArray();

      String s = new String(0, 10, c);

      }

      }

      String類有一個Package權限的構造函數String(int offset, int length, char[] array),按照默認的訪問權限,由于Test屬于java.lang包,因此理論上應該可以訪問String的這個構造函數。編譯通過!執行時結果如下:

      Exception in thread "main" java.lang.SecurityException: Prohibited package name:

      java.lang

      at java.lang.ClassLoader.defineClass(Unknown Source)

      at java.security.SecureClassLoader.defineClass(Unknown Source)

      at java.net.URLClassLoader.defineClass(Unknown Source)

      at java.net.URLClassLoader.access$100(Unknown Source)

      at java.net.URLClassLoader$1.run(Unknown Source)

      at java.security.AccessController.doPrivileged(Native Method)

      at java.net.URLClassLoader.findClass(Unknown Source)

      at java.lang.ClassLoader.loadClass(Unknown Source)

      at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)

      at java.lang.ClassLoader.loadClass(Unknown Source)

      at java.lang.ClassLoader.loadClassInternal(Unknown Source)

      奇怪吧?要弄清為什么會有SecurityException,就必須搞清楚ClassLoader的機制。

      Java的ClassLoader就是用來動態裝載class的,ClassLoader對一個class只會裝載一次,JVM使用的ClassLoader一共有4種:

      啟動類裝載器,標準擴展類裝載器,類路徑裝載器和網絡類裝載器。

      這4種ClassLoader的優先級依次從高到低,使用所謂的“雙親委派模型”。確切地說,如果一個網絡類裝載器被請求裝載一個java.lang.Integer,它會首先把請求發送給上一級的類路徑裝載器,如果返回已裝載,則網絡類裝載器將不會裝載這個java.lang.Integer,如果上一級的類路徑裝載器返回未裝載,它才會裝載java.lang.Integer。

      類似的,類路徑裝載器收到請求后(無論是直接請求裝載還是下一級的ClassLoader上傳的請求),它也會先把請求發送到上一級的標準擴展類裝載器,這樣一層一層上傳,于是啟動類裝載器優先級最高,如果它按照自己的方式找到了java.lang.Integer,則下面的ClassLoader 都不能再裝載java.lang.Integer,盡管你自己寫了一個java.lang.Integer,試圖取代核心庫的java.lang.Integer是不可能的,因為自己寫的這個類根本無法被下層的ClassLoader裝載。

      再說說Package權限。Java語言規定,在同一個包中的class,如果沒有修飾符,默認為Package權限,包內的class都可以訪問。但是這還不夠準確。確切的說,只有由同一個ClassLoader裝載的class才具有以上的Package權限。比如啟動類裝載器裝載了java.lang.String,類路徑裝載器裝載了我們自己寫的java.lang.Test,它們不能互相訪問對方具有Package權限的方法。這樣就阻止了惡意代碼訪問核心類的Package權限方法

     

    ava不是完美的,Java的不足除了體現在運行速度上要比傳統的C++慢許多之外,Java無法直接訪問到操作系統底層(如系統硬件等),為此Java使用native方法來擴展Java程序的功能。
      可以將native方法比作Java程序同C程序的接口,其實現步驟:
      1、在Java中聲明native()方法,然后編譯;
      2、用javah產生一個.h文件;
      3、寫一個.cpp文件實現native導出方法,其中需要包含第二步產生的.h文件(注意其中又包含了JDK帶的jni.h文件);
      4、將第三步的.cpp文件編譯成動態鏈接庫文件;
      5、在Java中用System.loadLibrary()方法加載第四步產生的動態鏈接庫文件,這個native()方法就可以在Java中被訪問了。


    JAVA本地方法適用的情況
    1.為了使用底層的主機平臺的某個特性,而這個特性不能通過JAVA API訪問

    2.為了訪問一個老的系統或者使用一個已有的庫,而這個系統或這個庫不是用JAVA編寫的

    3.為了加快程序的性能,而將一段時間敏感的代碼作為本地方法實現。


    首先寫好JAVA文件

    package com.hode.hodework.modelupdate;

    public class CheckFile
    {
    public native void displayHelloWorld();

    static
    {
    System.loadLibrary("test");
    }

    public static void main(String[] args) {
    new CheckFile().displayHelloWorld();
    }
    }
    然后根據寫好的文件編譯成CLASS文件
    然后在classes或bin之類的class根目錄下執行javah -jni com.hode.hodework.modelupdate.CheckFile,
    就會在根目錄下得到一個com_hode_hodework_modelupdate_CheckFile.h的文件
    然后根據頭文件的內容編寫com_hode_hodework_modelupdate_CheckFile.c文件
    #i nclude "CheckFile.h"
    #i nclude
    #i nclude

    JNIEXPORT void JNICALL Java_com_hode_hodework_modelupdate_CheckFile_displayHelloWorld(JNIEnv *env, jobject obj)
    {
    printf("Hello world!\n");
    return;
    }
    之后編譯生成DLL文件如“test.dll”,名稱與System.loadLibrary("test")中的名稱一致
    vc的編譯方法:cl -I%java_home%\include -I%java_home%\include\win32 -LD com_hode_hodework_modelupdate_CheckFile.c -Fetest.dll
    最后在運行時加參數-Djava.library.path=[dll存放的路徑]



    一. 什么是Native Method
    簡單地講,一個Native Method就是一個java調用非java代碼的接口。一個Native Method是這樣一個java的方法:該方法的實現由非java語言實現,比如C。這個特征并非java所特有,很多其它的編程語言都有這一機制,比如在C++中,你可以用extern "C"告知C++編譯器去調用一個C的函數。
    "A native method is a Java method whose implementation is provided by non-java code."
    在定義一個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).
    標識符native可以與所有其它的java標識符連用,但是abstract除外。這是合理的,因為native暗示這些方法是有實現體的,只不過這些實現體是非java的,但是abstract卻顯然的指明這些方法無實現體。native與其它java標識符連用時,其意義同非Native Method并無差別,比如native static表明這個方法可以在不產生類的實例時直接調用,這非常方便,比如當你想用一個native method去調用一個C的類庫時。上面的第三個方法用到了native synchronized,JVM在進入這個方法的實現體之前會執行同步鎖機制(就像java的多線程。)
    一個native method方法可以返回任何java類型,包括非基本類型,而且同樣可以進行異常控制。這些方法的實現體可以制一個異常并且將其拋出,這一點與java的方法非常相似。當一個native method接收到一些非基本類型時如Object或一個整型數組時,這個方法可以訪問這非些基本型的內部,但是這將使這個native方法依賴于你所訪問的java類的實現。有一點要牢牢記住:我們可以在一個native method的本地實現中訪問所有的java特性,但是這要依賴于你所訪問的java特性的實現,而且這樣做遠遠不如在java語言中使用那些特性方便和容易。
    native method的存在并不會對其他類調用這些本地方法產生任何影響,實際上調用這些方法的其他類甚至不知道它所調用的是一個本地方法。JVM將控制調用本地方法的所有細節。需要注意當我們將一個本地方法聲明為final的情況。用java實現的方法體在被編譯時可能會因為內聯而產生效率上的提升。但是一個native final方法是否也能獲得這樣的好處卻是值得懷疑的,但是這只是一個代碼優化方面的問題,對功能實現沒有影響。
    如果一個含有本地方法的類被繼承,子類會繼承這個本地方法并且可以用java語言重寫這個方法(這個似乎看起來有些奇怪),同樣的如果一個本地方法被fianl標識,它被繼承后不能被重寫。
    本地方法非常有用,因為它有效地擴充了jvm.事實上,我們所寫的java代碼已經用到了本地方法,在sun的java的并發(多線程)的機制實現中,許多與操作系統的接觸點都用到了本地方法,這使得java程序能夠超越java運行時的界限。有了本地方法,java程序可以做任何應用層次的任務。


    二.為什么要使用Native Method
    java使用起來非常方便,然而有些層次的任務用java實現起來不容易,或者我們對程序的效率很在意時,問題就來了。
    與java環境外交互:
    有時java應用需要與java外面的環境交互。這是本地方法存在的主要原因,你可以想想java需要與一些底層系統如操作系統或某些硬件交換信息時的情況。本地方法正是這樣一種交流機制:它為我們提供了一個非常簡潔的接口,而且我們無需去了解java應用之外的繁瑣的細節。
    與操作系統交互:
    JVM支持著java語言本身和運行時庫,它是java程序賴以生存的平臺,它由一個解釋器(解釋字節碼)和一些連接到本地代碼的庫組成。然而不管怎樣,它畢竟不是一個完整的系統,它經常依賴于一些底層(underneath在下面的)系統的支持。這些底層系統常常是強大的操作系統。通過使用本地方法,我們得以用java實現了jre的與底層系統的交互,甚至JVM的一些部分就是用C寫的,還有,如果我們要使用一些java語言本身沒有提供封裝的操作系統的特性時,我們也需要使用本地方法。
    Sun's Java
    Sun的解釋器是用C實現的,這使得它能像一些普通的C一樣與外部交互。jre大部分是用java實現的,它也通過一些本地方法與外界交互。例如:類 java.lang.Thread 的 setPriority()方法是用java實現的,但是它實現調用的是該類里的本地方法setPriority0()。這個本地方法是用C實現的,并被植入JVM內部,在Windows 95的平臺上,這個本地方法最終將調用Win32 SetPriority() API。這是一個本地方法的具體實現由JVM直接提供,更多的情況是本地方法由外部的動態鏈接庫(external dynamic link library)提供,然后被JVM調用。


    三.JVM怎樣使Native Method跑起來:
    我們知道,當一個類第一次被使用到時,這個類的字節碼會被加載到內存,并且只會回載一次。在這個被加載的字節碼的入口維持著一個該類所有方法描述符的 list,這些方法描述符包含這樣一些信息:方法代碼存于何處,它有哪些參數,方法的描述符(public之類)等等。
    如果一個方法描述符內有native,這個描述符塊將有一個指向該方法的實現的指針。這些實現在一些DLL文件內,但是它們會被操作系統加載到java程序的地址空間。當一個帶有本地方法的類被加載時,其相關的DLL并未被加載,因此指向方法實現的指針并不會被設置。當本地方法被調用之前,這些DLL才會被加載,這是通過調用 java.system.loadLibrary()實現的。

    最后需要提示的是,使用本地方法是有開銷的,它喪失了java的很多好處。如果別無選擇,我們可以選擇使用本地方法。

     




    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 在线观看免费a∨网站| 久久亚洲av无码精品浪潮| 亚洲国产欧洲综合997久久| 亚洲福利视频一区二区| 久久久久国色av免费看| 亚洲精品国产摄像头| 亚洲日韩精品一区二区三区无码| 131美女爱做免费毛片| 免费看黄福利app导航看一下黄色录像| 亚洲亚洲人成综合网络| 99在线精品免费视频九九视| 四虎影视永久在线精品免费| 亚洲成年人电影网站| 亚洲国产精品日韩| 免费精品国偷自产在线在线| 羞羞视频在线观看免费| 亚洲大香伊人蕉在人依线| 亚洲视频在线免费| 免费做爰猛烈吃奶摸视频在线观看 | 亚洲一区精品中文字幕| 国产福利免费在线观看| 999任你躁在线精品免费不卡| 美女裸体无遮挡免费视频网站| 亚洲日本乱码一区二区在线二产线| 久久久久亚洲?V成人无码| 性做久久久久久免费观看| 免费a级毛片无码a∨免费软件| 亚洲AV无码一区二区三区网址| 亚洲美女精品视频| 亚洲高清国产拍精品26U| 国产最新凸凹视频免费| 黄+色+性+人免费| 最新国产乱人伦偷精品免费网站| 在线观看亚洲视频| 在线亚洲高清揄拍自拍一品区| 亚洲av色影在线| 久久久久久A亚洲欧洲AV冫| 国产无遮挡又黄又爽免费视频| 日本阿v免费费视频完整版| 91av在线免费视频| 成全动漫视频在线观看免费高清版下载 |