先和你說(shuō)吧。str1和str2
創(chuàng)新互聯(lián)是一家網(wǎng)站設(shè)計(jì)公司,集創(chuàng)意、互聯(lián)網(wǎng)應(yīng)用、軟件技術(shù)為一體的創(chuàng)意網(wǎng)站建設(shè)服務(wù)商,主營(yíng)產(chǎn)品:成都響應(yīng)式網(wǎng)站建設(shè)公司、品牌網(wǎng)站制作、全網(wǎng)整合營(yíng)銷推廣。我們專注企業(yè)品牌在網(wǎng)站中的整體樹(shù)立,網(wǎng)絡(luò)互動(dòng)的體驗(yàn),以及在手機(jī)等移動(dòng)端的優(yōu)質(zhì)呈現(xiàn)。網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、移動(dòng)互聯(lián)產(chǎn)品、網(wǎng)絡(luò)運(yùn)營(yíng)、VI設(shè)計(jì)、云產(chǎn)品.運(yùn)維為核心業(yè)務(wù)。為用戶提供一站式解決方案,我們深知市場(chǎng)的競(jìng)爭(zhēng)激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞析悅目的作品,網(wǎng)站的價(jià)值服務(wù)。
都是引用類型,在棧中,里面存放
內(nèi)存地址。str1就是指向"hello"
string是引用類型。
public
static
void
fun(string
str2)這句中傳的是一個(gè)
str2的地址。這個(gè)地址也就是
str1中存的的地址。
現(xiàn)在在
棧中有兩個(gè)
引用
str1
和str2
。都是指向
常量池中的"hello"...
str2="mldn";你的這句代碼是
把
str2
指向常量池中的"mldn"
并沒(méi)有修改str1的值。
三樓在忽悠人,別聽(tīng)他的
Java Native Interface(JNI)是Java語(yǔ)言的本地編程接口,是J2SDK的一部分。在java程序中,我們可以通過(guò)JNI實(shí)現(xiàn)一些用java語(yǔ)言不便實(shí)現(xiàn)的功能。通常有以下幾種情況我們需要使用JNI來(lái)實(shí)現(xiàn)。 標(biāo)準(zhǔn)的java類庫(kù)沒(méi)有提供你的應(yīng)用程序所需要的功能,通常這些功能是平臺(tái)相關(guān)的 你希望使用一些已經(jīng)有的類庫(kù)或者應(yīng)用程序,而他們并非用java語(yǔ)言編寫的 程序的某些部分對(duì)速度要求比較苛刻,你選擇用匯編或者c語(yǔ)言來(lái)實(shí)現(xiàn)并在java語(yǔ)言中調(diào)用他們 下面我們開(kāi)始編寫HelloWorld程序,由于涉及到要編寫c/c++代碼因此我們會(huì)在開(kāi)發(fā)中使用Microsoft VC++工具。編寫java代碼,我們?cè)谟脖P上建立一個(gè)hello目錄作為我們的工作目錄,首先我們需要編寫自己的java代碼,在java代碼中我們會(huì)聲明native方法,代碼非常簡(jiǎn)單。如下所示 class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 注意我們的displayHelloWorld()方法的聲明,它有一個(gè)關(guān)鍵字native,表明這個(gè)方法使用java以外的語(yǔ)言實(shí)現(xiàn)。方法不包括實(shí)現(xiàn),因?yàn)槲覀円胏/c++語(yǔ)言實(shí)現(xiàn)它。注意System.loadLibrary("hello")這句代碼,它是在靜態(tài)初始化塊中定義的,系統(tǒng)用來(lái)裝載hello共享庫(kù),這就是我們?cè)诤竺嫔傻膆ello.dll(如果在其他的操作系統(tǒng)可能是其他的形式,比如hello.so) 編譯java代碼 javac HelloWorld.java 生成HelloWorld.class文件 創(chuàng)建.h文件 這一步中我們要使用javah命令生成.h文件,這個(gè)文件要在后面的c/c++代碼中用到,我們運(yùn)行 javah HelloWorld。這樣我們可以看到在相同目錄下生成了一個(gè)HelloWorld.h文件,文件內(nèi)容如下 在此我們不對(duì)他進(jìn)行太多的解釋。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include jni.h /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 編寫本地實(shí)現(xiàn)代碼 在這部分我們要用C/C++語(yǔ)言實(shí)現(xiàn)java中定義的方法,我們?cè)赩C++中新建一個(gè)Project,然后創(chuàng)建一個(gè)HelloWorldImp.cpp文件,內(nèi)容如下 #include jni.h #include "HelloWorld.h" #include stdio.h JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!\n"); return; } 注意我們這里include了 jni.h和剛才得到的HelloWorld.h文件。因此你要在VC++里面設(shè)置好,jni.h在JAVA_HOME/include里面。編譯通過(guò)后再生成hello.dll文件。 運(yùn)行java程序 把上面生成的hello.dll文件復(fù)制到我們的工作目錄,這時(shí)候我們的目錄中包括HelloWorld.java,HelloWorld.class和hello.dll文件。運(yùn)行java HelloWorld命令,則可在控制臺(tái)看到Hello world| 的輸出了。運(yùn)行VC++; 文件---新建---選“win32 console application”(控制臺(tái)程序)---在右方設(shè)置好路徑并輸入工程名---確定 接下來(lái)的幾個(gè)提示框點(diǎn)確定就行了,那是提示是否要用VC++提供的框架之類的 在左邊的工作空間中選“FILEVIEW”標(biāo)簽項(xiàng),點(diǎn)開(kāi)“+”號(hào),右鍵點(diǎn)擊“SOURCE FILES”,選“添加文件到目錄”,此即添加你要建立的C++源程序文件,會(huì)提示你沒(méi)有文件,是否添加,你點(diǎn)是,輸入文件名保存就OK了 然后SOURCE FILES下就出現(xiàn)了你剛才建立的*.CPP文件,雙擊,輸入代碼. 以下就是點(diǎn)”組建”菜單中的”編譯”、”組建”等命令進(jìn)行調(diào)試了。 相信你會(huì)了。
Jython(原JPython),是一個(gè)用Java語(yǔ)言寫的Python解釋器。 在沒(méi)有第三方模塊的情況下,通常選擇利用Jython來(lái)調(diào)用Python代碼, 它是一個(gè)開(kāi)源的JAR包,你可以到官網(wǎng)下載 一個(gè)HelloPython程序 importorg.python.util.PythonInterpreter; publicclassHelloPython{ publicstaticvoidmain(String[]args){ PythonInterpreterinterpreter=newPythonInterpreter(); interpreter.exec("print('hello')"); } } 什么是PythonInterpreter?它的中文意思即是“Python解釋器”。我們知道Python程序都是通過(guò)解釋器來(lái)執(zhí)行的,我們?cè)贘ava中創(chuàng)建一個(gè)“解釋器”對(duì)象,模擬Python解釋器的行為,通過(guò)exec("Python語(yǔ)句")直接在JVM中執(zhí)行Python代碼,上面代碼的輸出結(jié)果為:hello在Jvm中執(zhí)行Python腳本 interpreter.execfile("D:/labs/mytest/hello.py");如上,將exec改為execfile就可以了。需要注意的是,這個(gè).py文件不能含有第三方模塊,因?yàn)檫@個(gè)“Python腳本”最終還是在JVM環(huán)境下執(zhí)行的,如果有第三方模塊將會(huì)報(bào)錯(cuò):javaImportError:Nomodulenamedxxx 僅在Java中調(diào)用Python編寫的函數(shù) 先完成一個(gè)hello.py代碼: defhello(): return'Hello'在Java代碼中調(diào)用這個(gè)函數(shù): importorg.python.core.PyFunction; importorg.python.core.PyObject; importorg.python.util.PythonInterpreter; publicclassHelloPython{ publicstaticvoidmain(String[]args){ PythonInterpreterinterpreter=newPythonInterpreter(); interpreter.execfile("D:/labs/hello.py"); PyFunctionpyFunction=interpreter.get("hello",PyFunction.class);//第一個(gè)參數(shù)為期望獲得的函數(shù)(變量)的名字,第二個(gè)參數(shù)為期望返回的對(duì)象類型 PyObjectpyObject=pyFunction.__call__();//調(diào)用函數(shù) System.out.println(pyObject); } } 上面的代碼執(zhí)行結(jié)果為:Hello 即便只是調(diào)用一個(gè)函數(shù),也必須先加載這個(gè).py文件,之后再通過(guò)Jython包中所定義的類獲取、調(diào)用這個(gè)函數(shù)。 如果函數(shù)需要參數(shù),在Java中必須先將參數(shù)轉(zhuǎn)化為對(duì)應(yīng)的“Python類型”,例如: __call__(newPyInteger(a),newPyInteger(b))a,b的類型為Java中的int型,還有諸如:PyString(Stringstring)、PyList(Iteratoriter)等。 詳細(xì)可以參考官方的api文檔。 包含第三方模塊的情況:一個(gè)手寫識(shí)別程序 這是我和舍友合作寫的一個(gè)小程序,完整代碼在這里:,界面上引用了corejava上的一段代碼。Python代碼是舍友寫的,因?yàn)樵赑ython程序中使用了第三方的NumPy模塊,導(dǎo)致無(wú)法通過(guò)Jython執(zhí)行。下面這個(gè)方法純粹是個(gè)人思路,沒(méi)有深入查資料。核心代碼如下: importjava.io.*; classPyCaller{ privatestaticfinalStringDATA_SWAP="temp.txt"; privatestaticfinalStringPY_URL=System.getProperty("user.dir")+"\\test.py"; publicstaticvoidwriteImagePath(Stringpath){ PrintWriterpw=null; try{ pw=newPrintWriter(newFileWriter(newFile(DATA_SWAP))); }catch(IOExceptione){ e.printStackTrace(); } pw.print(path); pw.close(); } publicstaticStringreadAnswer(){ BufferedReaderbr; Stringanswer=null; try{ br=newBufferedReader(newFileReader(newFile(DATA_SWAP))); answer=br.readLine(); }catch(FileNotFoundExceptione){ e.printStackTrace(); }catch(IOExceptione){ e.printStackTrace(); } returnanswer; } publicstaticvoidexecPy(){ Processproc=null; try{ proc=Runtime.getRuntime().exec("python"+PY_URL); proc.waitFor(); }catch(IOExceptione){ e.printStackTrace(); }catch(InterruptedExceptione){ e.printStackTrace(); } } //測(cè)試碼 publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{ writeImagePath("D:\\labs\\mytest\\test.jpg"); execPy(); System.out.println(readAnswer()); } } 實(shí)際上就是通過(guò)Java執(zhí)行一個(gè)命令行指令。
//Java中怎么引用傳遞,在main中的代碼
public static void main(String[] args) {
Ldc l = new Ldc("你好");//這里的值可以改
System.out.println(l.str);
}
//----------------------------------------------------------------------------------------------------
//新建一個(gè)Ldc類代碼如果
public class Ldc {
public String str ="";
Ldc(String str){
this.str="我在這里返回你傳遞來(lái)的參數(shù):"+str;
}
}
Java調(diào)用C語(yǔ)言程序時(shí),主要是涉及到操作系統(tǒng)底層的事件。這種時(shí)間Java無(wú)法處理,例如用戶上傳一個(gè)視頻文件,需要后臺(tái)給視頻加上水印,或者后臺(tái)分離視頻流和音頻流。只能通過(guò)調(diào)用C語(yǔ)言處理。
使用Java如何去調(diào)用C語(yǔ)言的接口呢?使用Java的JNI技術(shù)。
具體調(diào)用步驟如下:
1.首先創(chuàng)建Java文件 HelloJni.java ,并創(chuàng)建native方法。
2.編譯Java文件并生成java頭文件。
3.創(chuàng)建C語(yǔ)言文件,HelloWorld.c。
4.生成動(dòng)態(tài)鏈接庫(kù)文件 libhello.so。
5.設(shè)置動(dòng)態(tài)鏈接庫(kù)文件的目錄。
6.把剛才生成的so文件拷貝到/home/lib下,然后執(zhí)行class文件。