靜態(tài)代碼塊在類加載時執(zhí)行,用于初始化類的一些信息。
成都創(chuàng)新互聯(lián)長期為1000多家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為臨城企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站設計,臨城網(wǎng)站改版等技術服務。擁有十余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
構造代碼塊在相應構造方法被調用時執(zhí)行,用于對象的初始化。
給出一個windows下dll的實例。linux下.a的靜態(tài)庫只是頭文件和編譯有所不同,另外需要將編譯后的動態(tài)庫文件放入/usr/lib下,使用ldconfig載入。
一 先制作一個系統(tǒng)中有的DLL文件(cpp給出的sdk接口)
既然是測試我們就把我們這個dll叫做testDll吧,為了簡單其間,我只寫一個add方法,就是簡單的2個數(shù)字相加,對于真正的開發(fā)中我們肯定會遇到其他類型,java到c/cpp中類型需要轉換,具體類型轉換對應關系g一下就能得到,我也不在列舉。c/cpp中一個class一般包含2個文件,一個頭文件定義(*.h),一個文件主體(*.c/*.cpp)。啰嗦了這么多還是直接動手吧,先在vs2008中建立一個工程(當然你也可以直接編寫不用這些IDE工具,gcc g++的命令自己g。下同,不在注釋不在廢話),選取win32工程
鍵入工程名字testDll,點擊next選取DLL,然后點擊完成
打開我們的testdll.cpp,添加進我們的add方法
C++代碼
1.int add(int a,int b){
2. return a+b;
3.}
int add(int a,int b){
return a+b;
}
注意到文件列表里并沒有testDll.h,因為我們要給出調用者一個接口,如果不給頭文件,人家就沒辦法調用,所以我們就必須添加一個頭文件testDll.h。
C++代碼
1.#ifdef TEST_DLL
2.#define TEST_API __declspec(dllexport)
3.#else
4.#define TEST_API __declspec(dllimport)
5.#endif
6.
7./* Set up for C function definitions, even when using C++ */
8.#ifdef __cplusplus
9.extern "C" {
10.#endif
11.
12.TEST_API int add(int,int);
13.
14./* Ends C function definitions when using C++ */
15.#ifdef __cplusplus
16.}
17.#endif
#ifdef TEST_DLL
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
TEST_API int add(int,int);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
在這個頭文件中我們把我們的add方法給定義了進去。注意到testdll.cpp中#include "stdafx.h",所以我們就把這個testDll.h include進stdafx.h里面。
按道理說我們的這個dll已經(jīng)完成了,但是一般c/cpp給接口SDK的時候大都給.h和.lib,為了一步生成dll和lib,我們添加進一個testDll.def,有了這個文件就可以一步生成dll和lib。在source file里右鍵add new item ,選擇Module-Definition File
鍵入testDll,OK了,我們可以直接build了。生成testDll.dll和testDll.lib。
把testDll.dll扔到system32目錄里等待我們高大威猛的java jni調用。
二 JNI
2.1 編寫java文件
為了顯示我們的與眾相同,我們就把我們的這個java文件命名為Demo.java順便直接帶上包名
,因為我們知道人家給我們的接口里有個add方法,所以我們就直接來個調用吧。
Java代碼
1.package com.testJni.testDemo;
2.
3.public class Demo {
4. static
5. {
6. //System.out.println(System.getProperty("java.library.path"));
7. System.loadLibrary("testDll");
8. System.loadLibrary("jniDll");
9. }
10. public native static int add(int a,int b);
11.
12.}
package com.testJni.testDemo;
public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
}
demo.java代碼暫時如此,我們把將要生成的jni的dll叫做jniDll,有童鞋講,我不想用你這個爛名字jniDll多俗啊,沒關系,你可以換,隨你換,生成文件后你再換也可以,現(xiàn)在換也可以。
2.2 生成.h頭文件
javah命令,不多講。生成的文件com_testJni_testDemo_Demo.h這個文件的命名規(guī)則我就不多講了,一目了然。
C++代碼
1./* DO NOT EDIT THIS FILE - it is machine generated */
2.#include jni.h
3./* Header for class com_testJni_testDemo_Demo */
4.
5.#ifndef _Included_com_testJni_testDemo_Demo
6.#define _Included_com_testJni_testDemo_Demo
7.#ifdef __cplusplus
8.extern "C" {
9.#endif
10./*
11. * Class: com_testJni_testDemo_Demo
12. * Method: add
13. * Signature: (II)I
14. */
15.JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
16. (JNIEnv *, jclass, jint, jint);
17.
18.#ifdef __cplusplus
19.}
20.#endif
21.#endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include jni.h
/* Header for class com_testJni_testDemo_Demo */
#ifndef _Included_com_testJni_testDemo_Demo
#define _Included_com_testJni_testDemo_Demo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_testJni_testDemo_Demo
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
2.3 用c/cpp實現(xiàn)這個頭文件
c/cpp中已經(jīng)實現(xiàn)了這個add方法,我們只需要調用就可以啦。所以直接vs2008中建立一個dll工程,工程名我們就叫jniDll,具體過程不再多講,方法同上面testDll的建立一樣。在這個工程里kimmking把需要引用的包、文件等已經(jīng)講的很清楚了。打開jniDll.cpp,添加下面代碼
C++代碼
1.JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
2.(JNIEnv *env,jclass jobject,jint a,jint b){
3.
4. return add(a,b);
5.}
JNIEXPORT jint JNICALL Java_com_testJni_testDemo_Demo_add
(JNIEnv *env,jclass jobject,jint a,jint b){
return add(a,b);
}因為int對應的類型就剛好是jint,所以就不需要轉換,其他需要轉換的類型自己g對應關系轉換,注意釋放。
這個工程里我們還需要打開 stdafx.h添加
C++代碼
1.#include jni.h
2.
3.#include "testDll.h"
4.#include "com_testJni_testDemo_Demo.h"
#include jni.h
#include "testDll.h"
#include "com_testJni_testDemo_Demo.h"
在編譯這個jniDll工程的時候需要引入testDll.h,com_testJni_testDemo_Demo.h,另外添加testDll.lib這個依賴。
好了做好這些后,build下,生成了我們期待已久的jniDll.dll,把這個dll同樣扔到system32下。
三 測試
本人特懶,不想寫多余的class,所以直接修改Demo.java 這也是剛才為什么講暫時如此的原因
Java代碼
1.package com.testJni.testDemo;
2.
3.public class Demo {
4. static
5. {
6. //System.out.println(System.getProperty("java.library.path"));
7. System.loadLibrary("testDll");
8. System.loadLibrary("jniDll");
9. }
10. public native static int add(int a,int b);
11. public static void main(String[] args) {
12. System.out.println(add(7,2));
13. }
14.}
package com.testJni.testDemo;
public class Demo {
static
{
//System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("testDll");
System.loadLibrary("jniDll");
}
public native static int add(int a,int b);
public static void main(String[] args) {
System.out.println(add(7,2));
}
}
四 最后補充
如果系統(tǒng)已經(jīng)加載過c/cpp的dll,我們就不用再System.loadLibrary("testDll")了,加載一遍就可以了,因為我們剛才寫的testDll系統(tǒng)沒有加載,所以我就加載了一下。對于多個dll可以寫多個System.loadLibrary去加載,修改static{}里面的內容不需要重新生成dll,除非你多加了一個調用方法,如果你看清楚規(guī)則,就不用javah命令就可以直接編寫頭文件,用javah太麻煩了。
一般情況下,如果有些代碼必須在項目啟動的時候就執(zhí)行的時候,需要使用靜態(tài)代碼塊,這種代碼是主動執(zhí)行的;需要在項目啟動的時候就初始化,在不創(chuàng)建對象的情況下,其他程序來調用的時候,需要使用靜態(tài)方法,這種代碼是被動執(zhí)行的.
兩者的區(qū)別就是:靜態(tài)代碼塊是自動執(zhí)行的;
靜態(tài)方法是被調用的時候才執(zhí)行的.
作用:靜態(tài)代碼塊可用來初始化一些項目最常用的變量或對象;靜態(tài)方法可用作不創(chuàng)建對象也可能需要執(zhí)行的代碼.
直接在類中定義且沒有加static關鍵字的代碼塊稱為{}構造代碼塊。構造代碼塊在創(chuàng)建對象時被調用,每次創(chuàng)建對象都會被調用,并且構造代碼塊的執(zhí)行次序優(yōu)先于類構造函數(shù)。
靜態(tài)代碼塊:在java中使用static關鍵字聲明的代碼塊。靜態(tài)塊用于初始化類,為類的屬性初始化。每個靜態(tài)代碼塊只會執(zhí)行一次。由于JVM在加載類時會執(zhí)行靜態(tài)代碼塊,所以靜態(tài)代碼塊先于主方法執(zhí)行。
注意:1 靜態(tài)代碼塊不能存在于任何方法體內。2 靜態(tài)代碼塊不能直接訪問靜態(tài)實例變量和實例方法,需要通過類的實例對象來訪問。
網(wǎng)站名稱:java靜態(tài)代碼庫 java 動態(tài)編譯和靜態(tài)編譯
文章網(wǎng)址:http://m.rwnh.cn/article42/doojhhc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供外貿建站、用戶體驗、商城網(wǎng)站、搜索引擎優(yōu)化、自適應網(wǎng)站、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)