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));
}
}
native关键字应用于方法以指示该方法在 native code using JNI (Java Native Interface) 中实现 . native是适用的修饰符 only for methods and we can’t apply it anywhere else . 在C,C中实现的方法称为本机方法或外来方法 .
11 回答
native
关键字应用于方法,以指示使用JNI(Java本机接口)以本机代码实现该方法 .它标志着一种方法,它将用其他语言实现,而不是用Java实现 . 它与JNI(Java Native Interface)一起使用 .
过去使用本机方法来编写性能关键部分,但随着Java变得越来越快,这现在不太常见了 . 当时需要本机方法
您需要从Java调用用其他语言编写的库 .
您需要访问只能从其他语言(通常为C)访问的系统或硬件资源 . 实际上,许多与真实计算机(例如磁盘和网络IO)交互的系统功能只能这样做,因为它们调用本机代码 .
另见Java Native Interface Specification
Minimal example 让事情更清楚:
Main.java :
Main.c :
Compile and run :
Output :
在Ubuntu 14.04 AMD64上测试 . 还使用了Oracle JDK 1.8.0_45 .
Example on GitHub给你玩 .
必须使用C函数名中的
_1
转义Java包/文件名中的下划线,如下所述:Invoking JNI functions in Android package name containing underscoreInterpretation :
它允许您:
使用Java中的任意汇编代码调用已编译的动态加载库(此处用C语言编写)
并将结果返回Java
这可以用于:
使用更好的CPU汇编指令(不是CPU便携式)在关键部分写入更快的代码
进行直接系统调用(不是OS便携式)
与低便携性的权衡 .
您也可以从C调用Java,但必须首先在C中创建JVM:How to call Java functions from C++?
Android NDK
除了您必须使用Android样板来设置它之外,这个概念在此上下文中完全相同 .
官方NDK存储库包含“规范”示例,例如hello-jni app:
https://github.com/googlesamples/android-ndk/blob/4df5a2705e471a0818c6b2dbc26b8e315d89d307/hello-jni/app/src/main/java/com/example/hellojni/HelloJni.java#L39
https://github.com/googlesamples/android-ndk/blob/4df5a2705e471a0818c6b2dbc26b8e315d89d307/hello-jni/app/src/main/cpp/hello-jni.c#L27
你在Android O上使用NDK
unzip
.apk
,你可以看到与lib/arm64-v8a/libnative-lib.so
下的本机代码对应的预编译.so
.TODO确认:此外,
file /data/app/com.android.appname-*/oat/arm64/base.odex
,表示它是一个共享库,我认为是AOT预编译的.dex对应于ART中的Java文件,另请参阅:What are ODEX files in Android?那么Java实际上也可以通过native
接口运行?Example in the OpenJDK 8
让我们找到jdk8u60-b27中定义
Object#clone
的位置 .我们将得出结论,它是通过
native
调用实现的 .首先我们发现:
这导致我们jdk/src/share/classes/java/lang/Object.java#l212:
现在是困难的部分,找到克隆在所有间接中的位置 . 帮助我的查询是:
可以找到可能实现Object的本机方法的C或C文件 . 它引导我们jdk/share/native/java/lang/Object.c#l47:
它引导我们到
JVM_Clone
符号:这导致我们hotspot/src/share/vm/prims/jvm.cpp#l580:
在扩展了一堆宏之后,我们得出结论,这是定义点 .
直接从the Java Language Specification:
正如SLaks所回答的那样,
native
关键字用于调用本机代码 .它也被GWT用于实现javascript方法 .
实现本机代码的函数声明为native .
http://en.wikipedia.org/wiki/Java_Native_Interface
NATIVE是非访问修饰符 . 它只能应用于METHOD . 它表示方法或代码的PLATFORM-DEPENDENT实现 .
native是java中的一个关键字,用于制作未实现的结构(方法),就像抽象一样,但它依赖于平台,例如本机代码,从本机堆栈执行而不是java堆栈 .
native
是java中的关键字,它表示平台依赖 .native
方法充当Java( JNI )和其他编程语言之间的接口 .native关键字应用于方法以指示该方法在 native code using JNI (Java Native Interface) 中实现 . native是适用的修饰符 only for methods and we can’t apply it anywhere else . 在C,C中实现的方法称为本机方法或外来方法 .
提高系统性能 .
实现任务级别/内存级别的通信 .
使用现有的旧版非Java代码 .
native关键字用于声明在与平台相关的代码(如C或C)中实现的方法 . 当一个方法被标记为本机时,它不能有一个正文,而必须以分号结尾 . Java Native Interface(JNI)规范管理用于实现本机方法的规则和指南,例如Java和本机应用程序之间的数据类型转换 .
以下示例显示了一个具有声明为native的方法的类: