java本地方法关键字_java 中本地方法調用---native關鍵字

以java中java.lang.System類中的一個得到系統當前時間的native方法為例,對native關鍵字進行說明:

__________________________________________________________

public final class System {//final關鍵字修飾的類不能被繼承

.......

/**

*返回系統當前時間(該方法依賴於底層操作系統的實現)

*/

public static native long currentTimeMillis();

.......

}

__________________________________________________________

對於上面的currentTimeMillis();聲明為native 表明:該方法的具體實現是依賴於底層的操作系統平台,並非java語言實現。

所以,一個native方法就是java調用非java代碼的接口,當在方法中調用一些不是由java語言寫的代碼或者在方法中用java語言

直接操縱計算機硬件時要聲明為native方法。native 方法中除了不能和abstract關鍵字連用(abstract表示方法是空實現,這顯然與native調用外部實現的事實不符),非native方法並無區別。

---

JAVA本地方法適用的情況

1.為了使用底層的主機平台的某個特性,而這個特性不能通過JAVA API訪問

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

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

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

類首次被使用到時,編譯生成字節碼會被加載到內存。在該字節碼的入口維持着一個該類所有方法描述符的列表,這些方法描述符包含了類的詳細信息。對應native方法,描述符塊中會有一個指向該方法的實現的指針。這些實現在一些DLL文件(動態鏈接庫文件dll是由java類編譯后的.h文件及jni.h文件信息和具體的方法實現等編譯生成的)內,當native方法被調用時,java會調用System.loadLibrary(*.dll)方法加載該dll。

其中,java通過javah(Javah:產生可以調用Java過程的C過程,或建立能被Java程序調用的C過程的頭文件)生成該類的.h文件。

jni(Java Native Interface,java本地接口)

------------------------------------------下面是加載dll文件的具體實現-------

Java代碼 f622d923d726a2911d1cb6b7de954ccc.gif663a9b3c4e5230b12c0daaacdb963b98.png

313f2111f37cc9d892a609259c857782.gif

/**

*java.lang.System中, 加載由 libname 參數指定的系統庫

*/

public static void loadLibrary(String libname) {//調用Runtime的loadLibrary方法

Runtime.getRuntime().loadLibrary0(getCallerClass(), libname);

}

/**

*Runtime的loadLibrary方法(帶有synchronized的同步方法)

*/

synchronized void loadLibrary0(Class fromClass, String libname) {

//用於判斷libname所指定文件的合法性

SecurityManager security = System.getSecurityManager();

if (security != null) {

security.checkLink(libname);

}

if (libname.indexOf((int)File.separatorChar) != -1) {

throw new UnsatisfiedLinkError(

"Directory separator should not appear in library name: " + libname);

}

//調用ClassLoader的loadLibrary方法

ClassLoader.loadLibrary(fromClass, libname, false);

}

/**

*ClassLoader的loadLibrary方法

*/

// Invoked in the java.lang.Runtime class to implement load and loadLibrary.

static void loadLibrary(Class fromClass, String name,boolean isAbsolute) {

try {

if (!DownloadManager.isJREComplete() &&

!DownloadManager.isCurrentThreadDownloading()) {

DownloadManager.downloadFile("bin/" + System.mapLibraryName(name));

}

} catch (Exception e) {

throw new UnsatisfiedLinkError("Error downloading library "

+ name + ": " + e);

}

ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader();

if (sys_paths == null) {

usr_paths = initializePath("java.library.path");

sys_paths = initializePath("sun.boot.library.path");

}

}

.......

}

/**

*java.lang.System中, 加載由 libname 參數指定的系統庫

*/

public static void loadLibrary(String libname) {//調用Runtime的loadLibrary方法

Runtime.getRuntime().loadLibrary0(getCallerClass(), libname);

}

/**

*Runtime的loadLibrary方法(帶有synchronized的同步方法)

*/

synchronized void loadLibrary0(Class fromClass, String libname) {

//用於判斷libname所指定文件的合法性

SecurityManager security = System.getSecurityManager();

if (security != null) {

security.checkLink(libname);

}

if (libname.indexOf((int)File.separatorChar) != -1) {

throw new UnsatisfiedLinkError(

"Directory separator should not appear in library name: " + libname);

}

//調用ClassLoader的loadLibrary方法

ClassLoader.loadLibrary(fromClass, libname, false);

}

/**

*ClassLoader的loadLibrary方法

*/

// Invoked in the java.lang.Runtime class to implement load and loadLibrary.

static void loadLibrary(Class fromClass, String name, boolean isAbsolute) {

try {

if (!DownloadManager.isJREComplete() &&

!DownloadManager.isCurrentThreadDownloading()) {

DownloadManager.downloadFile("bin/" + System.mapLibraryName(name));

}

} catch (Exception e) {

throw new UnsatisfiedLinkError("Error downloading library "

+ name + ": " + e);

}

ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader();

if (sys_paths == null) {

usr_paths = initializePath("java.library.path");

sys_paths = initializePath("sun.boot.library.path");

}

}

.......

}--------------------------------------------------------------------------------------------------------------------------------

另外,java.lang.System還用到了java中的另外兩個比較常見的關鍵字:final和static。

在這里也做簡單的說明:

關於final:

final修飾的類(比如System)表示該類不可被繼承,所以final不能修飾interface或abstract類;

final修飾的方法不能被子類覆蓋(不能被Override),不能修飾構造函數;

final修飾字段屬性、參數時表示其被第一次賦值后不能被修改(但這里請注意,如果是一個對象,

不能修改的是該對象的引用,但是對象的內容還是可以修改的)

使用final的 好處:

1.防止被修改;2.final類型的方法被調用時,編譯器會把它嵌入進來在一定程度上會提高了編譯效率(注意是:一定程度,原因如下)。

編譯器有一種被稱為inline的機制,它會使你在調用final方法時,直接將方法主體插入到調用處,而不是進行例行的方法調用,例如保存斷點,壓棧等,這樣可能會使你的程序效率有所提高,然而當你的方法主體非常龐大時,或你在多處調用此方法,那么你的調用主體代碼便會迅速膨脹,可能反而會影響效率,所以你要慎用final進行方法定義。

---------

關於static:

static 可以理解為“類”級別的關鍵字,因此對於static不存在this的概念,當類被jvm加載時,會按照聲明的先后對static成員字段進行初始化

於是,static 可用於定義全局變量,而 static final 就可以定義一個常量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值