首页 文章

Java中的native关键字是什么?

提问于
浏览
407

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

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

11 回答

  • 55

    native 关键字应用于方法,以指示使用JNI(Java本机接口)以本机代码实现该方法 .

  • 19

    它标志着一种方法,它将用其他语言实现,而不是用Java实现 . 它与JNI(Java Native Interface)一起使用 .

    过去使用本机方法来编写性能关键部分,但随着Java变得越来越快,这现在不太常见了 . 当时需要本机方法

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

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

    另见Java Native Interface Specification

  • 5

    Minimal example 让事情更清楚:

    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;
    }
    

    Compile and run

    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
    

    Output

    4
    

    在Ubuntu 14.04 AMD64上测试 . 还使用了Oracle JDK 1.8.0_45 .

    Example on GitHub给你玩 .

    必须使用C函数名中的 _1 转义Java包/文件名中的下划线,如下所述:Invoking JNI functions in Android package name containing underscore

    Interpretation

    它允许您:

    • 使用Java中的任意汇编代码调用已编译的动态加载库(此处用C语言编写)

    • 并将结果返回Java

    这可以用于:

    • 使用更好的CPU汇编指令(不是CPU便携式)在关键部分写入更快的代码

    • 进行直接系统调用(不是OS便携式)

    与低便携性的权衡 .

    您也可以从C调用Java,但必须首先在C中创建JVM:How to call Java functions from C++?

    Android NDK

    除了您必须使用Android样板来设置它之外,这个概念在此上下文中完全相同 .

    官方NDK存储库包含“规范”示例,例如hello-jni app:

    你在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 调用实现的 .

    首先我们发现:

    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");
    

    在扩展了一堆宏之后,我们得出结论,这是定义点 .

  • 377

    直接从the Java Language Specification

    本机方法是在依赖于平台的代码中实现的,通常用其他编程语言编写,例如C,C,FORTRAN或汇编语言 . 本机方法的主体仅以分号给出,表示省略了实现,而不是块 .

  • 6

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

    它也被GWT用于实现javascript方法 .

  • 7

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

    Java Native Interface(JNI)是一个编程框架,它使在Java虚拟机(JVM)中运行的Java代码能够调用本机应用程序(特定于硬件和操作系统平台的程序)和库编写的库来调用在其他语言,如C,C和汇编 .

    http://en.wikipedia.org/wiki/Java_Native_Interface

  • 3

    NATIVE是非访问修饰符 . 它只能应用于METHOD . 它表示方法或代码的PLATFORM-DEPENDENT实现 .

  • 1

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

  • 300
    • native 是java中的关键字,它表示平台依赖 .

    • native 方法充当Java( JNI )和其他编程语言之间的接口 .

  • 13

    native关键字应用于方法以指示该方法在 native code using JNI (Java Native Interface) 中实现 . native是适用的修饰符 only for methods and we can’t apply it anywhere else . 在C,C中实现的方法称为本机方法或外来方法 .

    native关键字的主要目标是:

    • 提高系统性能 .

    • 实现任务级别/内存级别的通信 .

    • 使用现有的旧版非Java代码 .

  • 362

    native关键字用于声明在与平台相关的代码(如C或C)中实现的方法 . 当一个方法被标记为本机时,它不能有一个正文,而必须以分号结尾 . Java Native Interface(JNI)规范管理用于实现本机方法的规则和指南,例如Java和本机应用程序之间的数据类型转换 .

    以下示例显示了一个具有声明为native的方法的类:

    public class NativeExample {
        public native void fastCopyFile(String sourceFile, String destFile);
    }
    

相关问题