¿Qué son estos nativos y cómo funcionan estos métodos?
ejemplo Mínimo para hacer las cosas más claras:
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;
}
Compilar y ejecutar:
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
salida:
4
probado en Ubuntu 14.04. También trabajé con Oracle JDK 1.8.0_45.
Example on GitHub para que juegues con.
Interpretación:
Se le permite:
- llamada de una biblioteca cargada dinámicamente compilado (aquí escrito en C) con el código de montaje arbitraria desde Java
- y obtener resultados de nuevo en Java
Esto podría usarse para:
- escribir código más rápido en una sección crítica con las instrucciones de la CPU mejor montaje (no portátiles CPU)
- realizar llamadas de sistema directo (no OS portátil)
con la compensación de la portabilidad inferior.
También es posible que usted pueda llamar a Java desde C, pero primero debe crear una JVM en C: How to call Java functions from C++?
Ejemplo en el OpenJDK 8
vamos a encontrar encontrar dónde Object#clone
se define en jdk8u60-b27.
En primer lugar nos encontramos con:
find . -name Object.java
que nos lleva a jdk/src/share/classes/java/lang/Object.java#l212:
protected native Object clone() throws CloneNotSupportedException;
Ahora viene la parte difícil, encontrar dónde clon es en medio de toda la vía indirecta. La consulta que me ayudó fue:
find . -iname object.c
que encontraría archivos C o C++ que podrían implementar los métodos nativos de Object.Nos lleva a 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]));
}
que nos lleva al símbolo JVM_Clone
:
grep -R JVM_Clone
que nos lleva a hotspot/src/share/vm/prims/jvm.cpp#l580:
JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
JVMWrapper("JVM_Clone");
Después de expandir un grupo de macros, llegamos a la conclusión de que este es el punto de definición.
si hashcode() está implementado por JVM solo ¿por qué requiere ser * native *? ¿A qué se refiere con * intrínseco * aquí? – Geek