當前位置:才華齋>計算機>java語言>

JNI是怎樣java調用c動態庫

java語言 閲讀(4.36K)

JNI是什麼 java調用c動態庫

JNI是怎樣java調用c動態庫

JNI是JavaNativeInterface的縮寫,中文為JAVA本地調用。從Java1.1開始,JavaNativeInterface(JNI)標準成為java平台的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他語言,只要調用約定受支持就可以了。

使用java與本地已編譯的代碼交互,通常會喪失平台可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統進行交互,或者為了提高程序的性能。JNI標準至少保證本地代碼能工作在任何Java虛擬機實現下。

編寫帶有native聲明的方法的java類

·使用javac命令編譯所編寫的java類

·使用javah?jnijava類名生成擴展名為h的頭文件

·使用C/C++實現本地方法

·將C/C++編寫的文件生成動態連接庫

·ok

1)編寫java程序:這裏以HelloWorld為例。

代碼1:

classHelloWorld{

publicnativevoiddisplayHelloWorld();

static{

Library("hello");

publicstaticvoidmain(String[]args){

newHelloWorld()layHelloWorld();

聲明native方法:如果你想將一個方法做為一個本地方法的話,那麼你就必須聲明改方法為native的,並且不能實現。其中方法的參數和返回值在後面講述。Load動態庫:Library("hello");加載動態庫(我們可以這樣理解:我們的方法displayHelloWorld()沒有實現,但是我們在下面就直接使用了,所以必須在使用之前對它進行初始化)這裏一般是以static塊進行加載的。同時需要注意的是Library();的參數“hello”是動態庫的名字。

2)編譯

沒有什麼好説的了

3)生成擴展名為h的頭文件javah?

jniHelloWorld頭文件的內容:/*DONOTEDITTHISFILE-itismachinegenerated*/

ude

/*HeaderforclassHelloWorld*/

ef_Included_HelloWorld

ne_Included_HelloWorld

f__cplusplus

extern"C"{

f

*Class:HelloWorld

*Method:displayHelloWorld

*Signature:()V

JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*,jobject);

f__cplusplus

f

f

(這裏我們可以這樣理解:這個h文件相當於我們在java裏面的接口,這裏聲明瞭一個Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);方法,然後在我們的本地方法裏面實現這個方法,也就是説我們在編寫C/C++程序的時候所使用的方法名必須和這裏的一致)。

4)編寫本地方法實現和由javah命令生成的頭文件裏面聲明的方法名相同的方法。

代碼2:

1#include"jni.h"

2#include"HelloWorld.h"

3//#includeotherheaders

4JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*env,jobjectobj)

printf("Helloworld! ");

return;

注意代碼2中的第1行,需要將jni.h(該文件可以在%JAVA_HOME%/include文件夾下面找到)文件引入,因為在程序中的JNIEnv、jobject等類型都是在該頭文件中定義的;另外在第2行需要將HelloWorld.h頭文件引入(我是這麼理解的:相當於我們在編寫java程序的時候,實現一個接口的話需要聲明才可以,這裏就是將HelloWorld.h頭文件裏面聲明的方法加以實現。當然不一定是這樣)。然後保存為HelloWorldImpl.c就ok了。

5)生成動態庫

這裏以在Windows中為例,需要生成dll文件。在保存HelloWorldImpl.c文件夾下面,使用VC的編譯器cl成。cl-I%java_home%include-I%java_home%注意:生成的dll文件名在選項-Fe後面配置,這裏是hello,因為在文件中我們loadLibary的時候使用的名字是hello。當然這裏修改之後那裏也需要修改。另外需要將-I%java_home%include-I%java_home%includewin32參數加上,因為在第四步裏面編寫本地方法的時候引入了jni.h文件。

6)運行程序javaHelloWorld就ok.

下面是一個簡單的例子實現打印一句話的功能,但是用的c的printf最終實現。一般提供給java的jni接口包括一個so文件(封裝了c函數的實現)和一個java文件(需要調用path的類)。

1.JNI的目的是使java方法中能夠調用c實現的一些函數,比如以下的java類,就需要調用一個本地函數testjni(一般聲明為privatenative類型),首先需要創建文件,內容如下:

classweiqiong{static{Library("testjni");//載入靜態庫,test函數在其中實現}privatenativevoidtestjni();//聲明本地調用publicvoidtest(){testjni();}publicstaticvoidmain(Stringargs[]){weiqionghaha=newweiqiong();();}}

2.然後執行,如果沒有報錯,會生成一個s。

3.然後設置classpath為你當前的工作目錄,如直接輸入命令行:setclasspath=s所在的完整目錄(如c: est)再執行javahweiqiong,會生成一個文件weiqiong.h文件,其中有一個函數的聲明如下:

JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*,jobject);

4.創建文件testjni.c將上面那個函數實現,內容如下:

ude

ude

JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*env,jobjectobj){printf("haha---------gointoc!!! ");}

5.為了生成文件,創建makefile文件如下:

:tjni.o:-Wall-ctestjni.c-I./-I/usr/java/j2sdk1.4.0/include-I/usr/java/j2sdk1.4.0/include/linuxcl:rm-rf*.o*注意:gcc前面是tab空,j2sdk的目錄根據自己裝的j2sdk的具體版本來寫,生成的so文件的名字必須是loadLibrary的參數名前加“lib”。

6.exportLD_LIBRARY_PATH=.,由此設置library路徑為當前目錄,這樣java文件才能找到so文件。一般的做法是將so文件copy到本機的LD_LIBRARY_PATH目錄下。

7.執行javaweiqiong,打印出結果:“haha---------gointoc!!!”

javascript 中(function{})()這種寫法什麼意思?

最近在整理javascript 學習,發現這個問題了 ,在網上發現這麼個解釋 最清楚 最明白 ;

(function(){})()

相當於先定義 function xx(){},後調用 xx();

()是最高優先級的,所以先執行function(){},

這個定義了一個匿名函數,等於xx=function(){}

接着就是調用xx()了;

給個例子

JScript codefunctionf1(a)

{ alert(a);

functionf2(a)

{ returnfunction(){ alert(a); }

}這裏的var x=f2 就等於把函數傳遞給了f2,然後要執行這個函數,就必須加() 也就是x();

也就是f2()

還是(function f2(a){

return function(){

alert(a);

另外還有一個問題就是命名空間的問題

YY = YY||{};---聲明一個叫YY的命名空間(定義一個全局的變量)

(function() {

=function() {------聲明一個叫的命名空間(通過全局變量的增加屬性的方式把閉包裏的對象傳到全局變量中,實現代碼封裝的效果)

isUndefined: function(o) {

return typeof o === 'undefined';

isString: function(o) {

return typeof o === 'string';

---調用方法

alert(ring('test me'));

這時候就有人不明瞭,樓上為什麼要加(function() { 和)(); 最外面的這兩行,有什麼用啊?

JScript codeYY=YY||{}; //---聲明一個叫YY的命名空間(定義一個全局的變量)

function() { =function() {

//------聲明一個叫的命名空間(通過全局變量的增加屬性的方式把閉包裏的對象傳到全局變量中,實現代碼封裝的效果) isUndefined:function(o) {returntypeofo==='undefined'; },

isString:function(o) {returntypeofo==='string'; } }; }

//---調用方法

alert(ring('test me'));

疑問在這: 註釋掉這兩行有什麼不一樣的呢?不就是申明嗎,為什麼要用()()執行一下啊?

答:

(function(){})()意思是立即執行前一個括號裏的function,相當於是一個匿名函數;由於裏面的代碼的執行,定義了這個對象,所以可以執行alert(ring('test me'));調用isString方法。

但是,如果按照你寫的

functionaa(){..};//只是定義了一個叫aa的函數,但是並沒有執行

alert(ring('test me'));//執行的時候會報找不到isString的方法。

這麼寫有什麼好處??

(function{})()的寫法有個好處,就是能很好的利用javascript的變量的可見範圍為執行腳本時節省空間。例如以下寫法1和寫法2達到的目的是一樣的,但是寫法1的由於a變量的可見範圍只是在匿名函數體內,所以a在執行完這個匿名函數後就釋放空間了。但是寫法2會一直存在該頁面中。

寫法1:

JScript code(function(){vara=2; alert(a); })();

寫法2:

JScript codevara=2; alert(a);

Java服務器軟件工程師試題

Java服務器軟件工程師試題一、 選擇題1. 欲構造ArrayList類的一個實例,此類繼承了List接口,下列哪個方法是正確的 ( )A ArrayList myList=new Object(); B List myList=new ArrayList(); C ArrayList myList=new List(); D List myList=new List(); 2. paint()方法使用哪種類型的參數? ( )A Graphics B Graphics2D C String D Color 3. 指出下列程序運行的.結果( ) public class Example{ String str=new String("good"); char[]ch={'a','b','c'}; public static void main(String args[]){ Example ex=new Example(); ge(,); t(+" and "); t(); } public void change(String str,char ch[]){ str="test ok"; ch[0]='g'; } } A good and abc B good and gbc C test ok and abc D test ok and gbc 4. 要從文件" "文件中讀出第10個字節到變量C中,下列哪個方法適合? ( )A FileInputStream in=new FileInputStream(""); (9); int c=(); B FileInputStream in=new FileInputStream(""); (10); int c=(); C FileInputStream in=new FileInputStream(""); int c=(); D RandomAccessFile in=new RandomAccessFile(""); (9); int c=Byte(); 5. 給出下面代碼,那個語句是正確的?( )public class Person{ static int arr[] = new int[10]; public static void main(String a[]) { tln(arr[1]); } } A 編譯時將產生錯誤; B 編譯時正確,運行時將產生錯誤; C 輸出零; D 輸出空。 7. 執行下面的hql查詢,關於返回值的説法,正確的是( ) select name,id from u where u is not nullA語法錯誤,不能執行B返回一個類型為List的實例C返回一個數組D當返回結果只有一條時,返回一個數組8. 下面的程序執行後沒有報錯,但數據總保存不到數據庫,最可能的原因 ( )public static void imain(String[] args){ SessionFactory sf=new Configration()igure()dSessionFactory(); Session session=Session(); Medal medal=new Medal(); wner(“totong”); ype(“Gold medal”); (user); e();}A配置文件配置有誤B沒有在配置文件中包含對映射文件的聲明C配置文件配置有誤D沒有對持久化操作捕捉異常E沒有開啟事務二、多項選擇題1. 執行下列代碼後,哪個結論是正確的 String[] s=new String[10]; ( )A s[10] 為 ""; B s[9] 為 null; C s[0] 為 未定義 D th 為10 2. 下列哪個方法可用於創建一個可運行的類? ( )A public class X implements Runable{ public void run(){ ......} } B public class X implements Thread{ public void run(){ ......} } C public class X implements Thread{ public int run(){ ......} } D public class X implements Runable{ protected void run(){ ......} } ic class X implements Thread{ public void run(){ ......} } 3. 下面哪個方法可以在任何時候被任何線程調用? ( )A notify() B wait() C notifyAll() D sleep() d() hronized(this) 4. 構造BufferedInputStream的合適參數是哪個? ( )A BufferedInputStream B BufferedOutputStream C FileInputStream D FileOuterStream E. File 5. 指出下列哪個方法與方法public void add(int a){}為合理的重載方法。 ( )A public int add(int a) B public void add(long a) C public void add(int a,int b) D public void add(float a) 6. JDBC可以做哪三件 ( )A 與數據庫建立連接B 通過JDBC-API向數據庫發送SQL語句C通過JDBC-API執行SQL語句D進行實體關係的映射 7. Hibernate通過____接口,____接口和Type層次體系來訪問元數據。( )A ClassMetadataB CollectionMetadataC MetadataD CollectionMeta三,問答題1.執行下列代碼後的結果是什麼? int x,a=2,b=3,c=4; x=++a+b+++c++;2.簡述什麼是設計模式,請描述你用過的幾種設計模式!3.從JAVA的角度理解,什麼是重構?ractclass和interface有什麼區別? r和exception有什麼區別?7.下列程序中構造了一個SET並且調用其方法add(),輸出結果是?public class A{ public int hashCode(){return 1;} public Boolean equals(Object b){return true} public static void main(String args[]){ Set set=new HashSet(); (new A()); (new A()); (new A()); tln(()); } } 8、請説出你所知道的線程同步的方法9、如果系統要使用超大整數(超過long長度範圍),請你設計一個數據結構來存儲這種超大型數字以及設計一種算法來實現超大整數加法運算

甲骨文分羹Android 谷歌藉機升級"山寨"Java

導讀:近年來,各種專利訴訟案頻發,各個廠商對自有專利的所有權和使用權越發的重視,一方是維護自己的權利、增加營收範圍,一方是防止同行分享自己辛苦的經營成果,孰是孰非可謂見仁見智。

天極網4月26日消息,在4月25日的甲骨文起訴GoogleAndroid系統侵權案的審判中,一名Android前任工程師伯恩斯坦(DanBornstein)承認,去年在遭到起訴後,他曾負責在Android中移除了部分Java技術。

伯恩斯坦表示,Android是一個“活的項目”,隨時都在修改調整,並稱這部分Java技術是通過瑞士的一個軟件開發承包商Noser帶到Android中的,當時Android方面曾建議該公司哪些技術可以移植到Android,哪些則不可以。

(甲骨文分羹Android谷歌可藉機升級“山寨”Java)

事件回顧

甲骨文在收購了Sun公司並獲得Java專利權後,於2010年8月將Google告上法庭,指控其Android操作系統侵犯了Java技術專利,並要求賠償10億美元。

在今年3月底,Google表示願意向甲骨文支付兩項專利的2011年費用,共計280萬美元。至於未來的賠償,Google提議將Android營收0.5%作為一項專利的費用,此專利今年12月到期;另外將0.015%的營收作為第二項專利的費用,此專利2018年4月到期。但甲骨文對此的迴應則是“Google開出的賠償額度太低了”。

Google表態:所用技術無需授權

3月25日,“Android之父”Google高層安迪·魯賓也在法庭上作證,他強調,“Android開發中所使用了Java部分不需要專利授權的技術,所以無需支付專利費,也不需要獲得甲骨文的授權。”

有報道稱,在去年專利訴訟發生的前幾周,一封Google內部郵件透露,當時Google創始人拉里·佩吉(LarryPage)和塞爾吉·布林(SergeyBrin)曾要求“調查哪種技術可以成為Android中Java的替代方案”,而最終的討論結果是“我們尋找了許多方案都不行,因此得出結論:我們要商討Java授權。”

分羹Android

法庭文件披露,谷歌曾經在2010年預測,到2013年,來自Android的相關收入(包括廣告、軟件產品、數字音樂消費等)將會高達37億美元。

甲骨文如此大動干戈的索要Java技術授權費,一定程度上也是看準了Android的巨大價值潛力,而Google方面千方百計的推脱責任,或許也是在為繼續尋求Java替代方案拖延時間,或者想要爭取更低的授權費用。

近年來,各種專利訴訟案頻發,各個廠商對自有專利的所有權和使用權越發的重視,一方是維護自己的權利、增加營收範圍,一方是防止同行分享自己辛苦的經營成果,孰是孰非可謂見仁見智,而雙方為之付出的巨大精力和財力是顯而易見的。

隨着訴訟的發展進程,Google方面並不佔據優勢,若最終甲骨文贏得官司,甲骨文則可獲得上億美元的專利費,而Google也有機會將其“山寨”Java升級為“正版”Java,對於Android系統的完善也不失是件好事。而目前Google最應該做的就是想辦法説服甲骨文降低專利授權費用。

Java語言中面向對象是什麼意思

何謂面向對象是什麼意思呢?

面向對象程序設計是將人們認識世界過程中普遍採用的思維方法應用到程序設計中。對象是現實世界中存在的事物,它們是有形的,如某個人、某種物品;也可以是無形的,如某項計劃、某次商業交易。對象是構成現實世界的一個獨立單位,人們對世界的認識,是從分析對象的特徵入手的。

對象的特徵分為靜態特徵和動態特徵兩種。靜態的特徵指對象的外觀、性質、屬性等;動態的特徵指對象具有的功能、行為等。客觀事物是錯綜複雜的,但人們總是從某一目的出發,運用抽象分析的能力,從眾多的特徵中抽取最具代表性、最能反映對象本質的若干特徵加以詳細研究。

人們將對象的靜態特徵抽象為屬性,用數據來描述,在Java語言中稱之為變量;人們將對象的動態特徵抽象為行為,用一組代碼來表示,完成對數據的操作,在Java語言中稱之為方法,。一個對象由一組屬性和一組對屬性進行操作的方法構成。

Java語言優點介紹

Java語言的優點

Java語言是一種優秀的編程語言。它最大的優點就是與平台無關,在Windows 9x、Windows NT、Solaris、Linux、MacOS以及其它平台上,都可以使用相同的代碼。“一次編寫,到處運行”的特點,使其在互聯網上被廣泛採用。

由於Java語言的設計者們十分熟悉C++語言,所以在設計時很好地借鑑了C++語言。可以説,Java語言是一種比C++語言“還面向對象”的一種編程語言。Java語言的語法結構與C++語言的語法結構十分相似,這使得C++程序員學習Java語言更加容易。

當然,如果僅僅是對C++改頭換面,那麼就不會有今天的Java熱了。Java語言提供的一些有用的新特性,使得使用Java語言比C++語言更容易寫出“無錯代碼”。

這些新特性包括:

1、提供了對內存的自動管理,程序員無需在程序中進行分配、釋放內存,那些可怕的內存分配錯誤不會再打擾設計者了;

2、去除了C++語言中的令人費解、容易出錯的“指針”,用其它方法來進行彌補;

3、避免了賦值語句(如a = 3)與邏輯運算語句(如a = = 3)的混淆;

4、取消了多重繼承這一複雜的概念。