Java中的本机关键字用于什么?

Java中的本机关键字用于什么?,java,java-native-interface,native,keyword,Java,Java Native Interface,Native,Keyword,在玩(这是一个Java关键字琐事游戏)时,我遇到了native关键字 Java中的native关键字用于什么?将native关键字应用于一个方法,以指示该方法是使用JNI(Java native Interface)在本机代码中实现的。正如SLaks回答的那样,native关键字用于调用本机代码 它还用于实现javascript方法。它标记了一个方法,该方法将用其他语言实现,而不是Java。它与JNI(Java本机接口)一起工作 本机方法过去用于编写性能关键部分,但随着Java速度的提高,这种情

在玩(这是一个Java关键字琐事游戏)时,我遇到了
native
关键字


Java中的native关键字用于什么?

native
关键字应用于一个方法,以指示该方法是使用JNI(Java native Interface)在本机代码中实现的。

正如SLaks回答的那样,
native
关键字用于调用本机代码


它还用于实现javascript方法。

它标记了一个方法,该方法将用其他语言实现,而不是Java。它与JNI(Java本机接口)一起工作

本机方法过去用于编写性能关键部分,但随着Java速度的提高,这种情况现在不太常见。当需要时,当前需要本机方法

  • 您需要从用其他语言编写的Java调用库

  • 您需要访问只能从其他语言(通常是C)访问的系统或硬件资源。实际上,许多与真实计算机交互的系统功能(例如,磁盘和网络IO)只能这样做,因为它们调用本机代码

另见

直接从:

一种方法,是代码>原生<代码>,它是在平台相关代码中实现的,通常用C、C++、FORTRAN或汇编语言等另一种编程语言编写。

native
方法的主体仅以分号形式给出,表示省略了实现,而不是块


实现本机代码的函数被声明为本机

java原生接口(JNI)是一种编程框架,它允许java虚拟机(JVM)中运行的java代码调用本地程序(特定于硬件和操作系统平台的程序)和用其他语言编写的库,如C、C++和汇编。


native是java中的一个关键字,用于使未实现的结构(方法)像抽象的一样,但它将是一个依赖于平台的结构,如本机代码,并从本机堆栈而不是java堆栈执行。

native是非访问修饰符。它只能应用于方法。
它表示方法或代码的平台相关实现。

最小可运行示例

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;
}
输出:

4
在Ubuntu 14.04 AMD64上测试。还与Oracle JDK 1.8.045合作

给你玩

Java包/文件名中的下划线必须在C函数名中用
\u 1
转义,如下所述:

解释

native
允许您:

  • 使用Java中的任意汇编代码调用编译的动态加载库(此处用C编写)
  • 并将结果返回到Java中
这可用于:

  • 使用更好的CPU汇编指令在关键部分编写更快的代码(不是CPU可移植的)
  • 直接进行系统调用(非操作系统便携式)
在可移植性较低的情况下进行权衡

您也可以从C调用Java,但必须首先在C中创建JVM:

出于同样的原因,类似的本机扩展API也出现在许多其他“VM语言”中,例如

安卓NDK

这个概念在本文中是完全相同的,只是您必须使用Android样板进行设置

官方NDK存储库包含“规范”示例,如hello jni应用程序:

在Android O上使用NDK解压
一个
.apk
时,可以看到预编译的
.so
,它对应于
lib/arm64-v8a/libnative lib.so下的本机代码

TODO确认:此外,
file/data/app/com.android.appname-*/oat/arm64/base.odex
,说它是一个共享库,我认为它是与ART中Java文件相对应的AOT预编译的.dex,另请参见:那么Java实际上也可能通过
本机
接口运行

OpenJDK 8中的示例

让我们来查找jdk8u60-b27中定义了
Object#clone
的位置

我们将得出结论,它是通过
native
调用实现的

首先,我们发现:

find . -name Object.java
这导致我们:

现在是最困难的部分,在所有的间接过程中找到克隆人的位置。帮助我的问题是:

find . -iname object.c
它会找到C或C++文件,这些文件可能实现对象的本机方法。它引导我们:

这将我们引向
JVM\u克隆
符号:

grep -R JVM_Clone
这导致我们:

在扩展了一系列宏之后,我们得出结论,这就是定义点。

  • native
    是java中的一个关键字,表示依赖于平台
  • native
    方法充当Java(JNI)和其他编程语言之间的接口
Java
native
方法提供了一种机制,使Java代码能够调用操作系统的本机代码,无论是出于功能还是性能方面的原因

例如:

  • ()包含以下本机方法定义
在OpenJDK中相应的
Runtime.class
文件中,位于
JAVA_HOME/jmods/JAVA.base.jmod/classes/JAVA/lang/Runtime.class
,包含这些方法并用
ACC_NATIVE
标记它们(
0x0100
),这些方法不包含,这意味着这些方法在
Runtime.class
文件中没有任何实际的编码逻辑:

  • 方法13可用的处理器:标记为本机和无代码属性
  • 方法14
    freemory
    :标记为本机和无代码属性
  • 方法15
    totalMemory
    :标记为本机和无代码属性
  • 方法16
    maxMemory
    :标记为本机和无代码属性
  • 方法17
    gc
    find . -iname object.c
    
    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]));
    }
    
    grep -R JVM_Clone
    
    JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
        JVMWrapper("JVM_Clone");
    
    606  public native int availableProcessors();
    617  public native long freeMemory();
    630  public native long totalMemory();
    641  public native long maxMemory();
    664  public native void gc();
    
    42  #include "java_lang_Runtime.h"
    43
    44  JNIEXPORT jlong JNICALL
    45  Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
    46  {
    47      return JVM_FreeMemory();
    48  }
    49
    50  JNIEXPORT jlong JNICALL
    51  Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
    52  {
    53      return JVM_TotalMemory();
    54  }
    55
    56  JNIEXPORT jlong JNICALL
    57  Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
    58  {
    59      return JVM_MaxMemory();
    60  }
    61
    62  JNIEXPORT void JNICALL
    63  Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
    64  {
    65      JVM_GC();
    66  }
    67  
    68  JNIEXPORT jint JNICALL
    69  Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
    70  {
    71      return JVM_ActiveProcessorCount();
    72  }