Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中使用本机_Java_Native - Fatal编程技术网

在Java中使用本机

在Java中使用本机,java,native,Java,Native,有人能解释一下在Java中使用本机关键字的原因吗 您可能有一个非Java库,无论出于何种原因,您必须在Java项目中使用它 您可能需要集成一些旧的或很少使用的硬件,并且需要实现在C/C中更容易实现的接口++ 如果您想用本机代码解决性能问题,则有99.5%的可能性认为这是错误的方法;-) Java是独立于平台的,这意味着用Java编写的程序可以在任何操作系统上运行—您甚至不需要重新编译,编译的类文件应该在任何操作系统上运行 然而,有时,您需要在程序中执行某些特定于某个操作系统的操作,并且可能没有一

有人能解释一下在Java中使用本机关键字的原因吗

  • 您可能有一个非Java库,无论出于何种原因,您必须在Java项目中使用它
  • 您可能需要集成一些旧的或很少使用的硬件,并且需要实现在C/C中更容易实现的接口++

  • 如果您想用本机代码解决性能问题,则有99.5%的可能性认为这是错误的方法;-)

    Java是独立于平台的,这意味着用Java编写的程序可以在任何操作系统上运行—您甚至不需要重新编译,编译的类文件应该在任何操作系统上运行

    然而,有时,您需要在程序中执行某些特定于某个操作系统的操作,并且可能没有一种纯Java的方式来执行您需要执行的操作;或者您可能需要调用现有的非Java库。Java平台提供(Java本机接口)作为调用操作系统特定代码的方式

    但是,您应该谨慎使用本机代码,因为它将您的程序与特定的操作系统联系在一起。

    这里引用了《有效Java第二版》第54项:明智地使用本机方法:

    历史上,本地方法有三个主要用途。它们提供对特定于平台的设施(如注册表和文件锁)的访问。它们提供了对遗留代码库的访问,而这些库又可以提供对遗留数据的访问。最后,使用本机方法以本机语言编写应用程序的性能关键部分,以提高性能

    使用本机方法访问特定于平台的设施是合法的,但随着Java平台的成熟,它提供了mroe和以前仅在主机平台中发现的更多功能。[…]很少建议使用本机方法来提高性能[…]

    使用本地方法有严重的缺点。因为本机语言不安全,所以使用本机方法的应用程序不再能够避免内存损坏错误。因为本机语言依赖于平台,所以使用本机方法的应用程序的可移植性要差得多。使用本机代码的应用程序很难进行调试。进入和退出本机代码有一个固定的成本,因此本机方法如果只做少量工作,就会降低性能。最后,本机方法需要“粘合代码”,这很难阅读,也很乏味

    整个项目对这些问题有更详细的解释。连同整本书,这是强烈推荐

    另见

    作为一名web开发人员,如果您使用Google web Toolkit,您很可能会遇到
    本机
    。使用该框架,您可以编写Java代码,然后将其编译为可以在浏览器中运行的Javascript。在GWT中,
    native
    关键字用于调用“native”Javascript代码

    要寻找的术语是

    • 演出
    • 与本机环境的更紧密集成
    • 需要使用具有独特功能的本机库

    示例:JAI(图像处理)、java3d(OpenGL)、JDIC(桌面集成)

    根据我的经验,使用本机代码库的缺点非常明显:

    • JNI/JNA倾向于破坏JVM的稳定性,特别是当您试图做一些复杂的事情时。如果本机代码的本机代码内存管理错误,则有可能导致JVM崩溃。如果您的本机代码是不可重入的,并且被多个Java线程调用,那么糟糕的事情就会发生。。。零星等等

    • 带有本机代码的Java比纯Java或纯C/C++更难调试

    • 本机代码可能会为其他与平台无关的Java应用程序带来重大的平台依赖性/问题

    • 本机代码需要一个单独的构建框架,并且可能存在平台/可移植性问题

    一般来说,使用本机代码不会获得太多(如果有的话)额外性能。虽然你可能认为C/C++会比java更具性能,但JIT编译器在这些天里做得很好,你必须考虑JNI调用和JNI边界上的其他交互的性能成本。


    通常,您应该将JNI/JNA视为“最后的选择”。如果有任何其他方法可以解决这个问题,那么这种方法可能更好。

    GWT的HTML小部件类有一个非常适合打印的宝石。如果要检查漂亮的打印机代码,则没有太大帮助:(

    有人能解释一下在Java中使用本机关键字的原因吗

    一旦你看到一个小例子,你就会明白:

    Main.java

    public class Main {
        public native int intMethod(int i);
        public static void main(String[] args) {
            System.loadLibrary("Main");
            System.out.println(new Main().intMethod(2));
        }
    }
    
    #include <jni.h>
    #include "Main.h"
    
    JNIEXPORT jint JNICALL Java_Main_intMethod(
        JNIEnv *env, jobject obj, jint i) {
      return i * i;
    }
    
    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
    
    Main.c

    public class Main {
        public native int intMethod(int i);
        public static void main(String[] args) {
            System.loadLibrary("Main");
            System.out.println(new Main().intMethod(2));
        }
    }
    
    #include <jni.h>
    #include "Main.h"
    
    JNIEXPORT jint JNICALL Java_Main_intMethod(
        JNIEnv *env, jobject obj, jint i) {
      return i * i;
    }
    
    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
    
    输出

    public class Main {
        public native int intMethod(int i);
        public static void main(String[] args) {
            System.loadLibrary("Main");
            System.out.println(new Main().intMethod(2));
        }
    }
    
    #include <jni.h>
    #include "Main.h"
    
    JNIEXPORT jint JNICALL Java_Main_intMethod(
        JNIEnv *env, jobject obj, jint i) {
      return i * i;
    }
    
    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
    
    在带有Oracle JDK 1.8.0_45的Ubuntu 14.04上测试

    因此,很明显,它允许您:

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

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

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

    给你玩


    免责声明:这个答案的一部分来自。我相信我已经直接回答了OP的问题。

    这真的有助于提高性能吗?人们对此有不同的想法!Java在访问底层硬件或操作系统提供的功能时总是需要一些本机代码。这取决于您是否需要了解about它(例如,因为如此