Usage of native in Java

This question already has an answer here:

  • What is the native keyword in Java for? 11 answers

  • In my experience, the downsides of using native code libraries are significant:

  • JNI / JNA have a tendency to destabilize the JVM, especially if you try to do something complicated. If your native code gets native code memory management wrong, there's a chance that you will crash the JVM. If your native code is non-reentrant and gets called from more than one Java thread, bad things will happen ... sporadically. And so on.

  • Java with native code is harder to debug than pure Java or pure C/C++.

  • Native code can introduce significant platform dependencies / issues for an otherwise platform independent Java app.

  • Native code requires a separate build framework, and that may have platform / portability issues as well.

  • Generally speaking, you don't gain much (if any) extra performance by using native code. While you might think your C/C++ will be more performant than Java, the JIT compiler does a pretty good job of optimizing these days, and you have to consider the performance costs of making JNI calls and other interactions across the JNI boundary.

    Generally specking, you should treat JNI / JNA as a "last resort" option. If there is any other way of solving the problem, that way is probably better.


  • You may have a non-Java library that for whatever reasons you have to use in your Java project
  • You may need to integrate some old or rarely used hardware and need to implement the interface which may be much easier in C/C++
  • If you want to solve a performance issue with native code than there's a 99.5% chance that this is the wrong approach ;-)


    Can someone explain the whys and the wherefores for using native keyword in Java?

    Once you see a small example, it becomes clear:

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

    Main.c :

    #include <jni.h>
    #include "Main.h"
    
    JNIEXPORT jint JNICALL Java_Main_intMethod(
        JNIEnv *env, jobject obj, jint i) {
      return i * i;
    }
    

    Compile and run :

    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
    

    Tested on Ubuntu 14.04 with Oracle JDK 1.8.0_45.

    So it is clear that it allows you to:

  • call a compiled dynamically loaded library (here written in C) with arbitrary assembly code from Java
  • and get results back into Java
  • This could be used to:

  • write faster code on a critical section with better CPU assembly instructions (not CPU portable)
  • make direct system calls (not OS portable)
  • with the tradeoff of lower portability.

    It is also possible for you to call Java from C, but you must first create a JVM in C: How to call Java functions from C++?

    Example on GitHub for you to play with.

    DISCLAIMER: part of this answer comes from my earlier answer. I believe that I have directly answered the OP's question in each.

    链接地址: http://www.djcxy.com/p/96824.html

    上一篇: Java方法和本地方法有什么区别?

    下一篇: 在Java中使用native