如果我們看一下Java對象類,那麼,我們可以找到一些像的方法:Java中的本地實現是什麼?
public native int hashCode()
protected native Object clone()
這些是什麼當地人和如何做這些方法的工作?
如果我們看一下Java對象類,那麼,我們可以找到一些像的方法:Java中的本地實現是什麼?
public native int hashCode()
protected native Object clone()
這些是什麼當地人和如何做這些方法的工作?
這些方法要麼是固有的要麼寫在外部Java中的「本地」代碼,即特定於給定機器。
您提到的是固有的和JDK的一部分,但您也可以使用Java Native Interface(JNI)自己編寫本機方法。這通常使用C來編寫方法,但是很多其他語言(如python)允許您以相當簡單的方式編寫方法。代碼是以這種方式編寫的,無論是爲了性能,還是因爲它需要訪問平臺特定的基礎結構,而這些基礎結構不能用普通的java來完成。
在hashcode()
的情況下,這由JVM實現。這是因爲散列碼通常只與JVM知道的東西有關。在早期的JVM上,這與對象在內存中的位置有關 - 在其他JVM上,對象可能在內存中移動,因此可能會使用更復雜(但仍然非常快)的方案。
Java中的本地方法使用被稱爲JNI的'Java Native Interface'實現。
本機方法主要以C語言實現,並編譯爲直接在機器上運行的本機代碼。 這與普通方法相反,普通方法在Java中實現並編譯爲由Java虛擬機(JVM)執行的Java字節代碼。
要從Java接口到這些方法,您需要使用Java Native Interface (JNI)。
本機代碼主要用於訪問低級別的東西。在hashCode的情況下,這是內存中對象的地址。我對克隆的猜測是它將原始內存從給定對象複製到克隆的對象。本地代碼的其他用途是訪問操作系統功能或硬件。
使用本機代碼的缺點是您失去了JVM的安全性,即由於本機代碼中的錯誤,您的程序可能會崩潰或存在安全漏洞。
大多數本地方法都是使用JNI實現的,如其他答案中所述。
但是,諸如Object.hashCode
等性能關鍵方法通常作爲內在函數實現。當字節代碼被編譯爲機器代碼時,Java編譯器會識別方法調用並直接對適當的代碼進行內聯。這顯然比通過JNI處理一個簡單的方法要快得多。
很多人會聲稱Object.hashCode
會返回內存中對象表示的地址。在現代實現中,對象實際上在內存中移動相反,對象頭部的一個區域用於存儲該值,該值可能是在第一次請求該值時從內存地址延遲派生的。
欲瞭解更多詳情[請訪問](http://stackoverflow.com/a/13860488/390695) – 2012-12-13 13:21:40
這些土着人是什麼人,這些方法是如何工作的?
小例子使事情更清晰:
Main.java:
public class Main {
public native int square(int i);
public static void main(String[] args) {
System.loadLibrary("Main");
System.out.println(new Main().square(2));
}
}
MAIN.C:
#include <jni.h>
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_square(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}
編譯並運行:
sudo apt-get install build-essential openjdk-7-jdk
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-amd64'
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
輸出:
4
測試在Ubuntu 14.04。還與Oracle JDK 1.8.0_45合作。
解讀:
它允許你:
這可用於:
低便攜性的權衡。
也可以爲你從C調用Java,但你必須在C首先創建一個JVM:在OpenJDK的8
How to call Java functions from C++?
例子讓我們找到尋找到Object#clone
的定義jdk8u60-B27。
首先,我們發現:
find . -name Object.java
這使我們jdk/src/share/classes/java/lang/Object.java#l212:
protected native Object clone() throws CloneNotSupportedException;
現在到了最困難的部分,發現其中克隆之中所有的間接。幫助我的查詢是:
find . -iname object.c
哪些可以找到可能實現Object的本機方法的C或C++文件。它使我們jdk/share/native/java/lang/Object.c#l47:
static JNINativeMethod methods[] = {
...
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
這使我們的JVM_Clone
符號:
grep -R JVM_Clone
這使我們hotspot/src/share/vm/prims/jvm.cpp#l580:
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
擴大了一堆宏之後,我們來得出這是定義的結論。
如果hashcode()僅由JVM實現,爲什麼它需要* native *?你究竟在這裏指的是什麼? – Geek 2013-08-31 11:25:46