native关键字

本文最后更新于:2020年12月4日 凌晨

初见
今天在看Thread start方法源码时其中的start0方法中的出现了native关键字

private native void startO();

native关键字是啥呢?

google
当java中的方法用native来修饰的时候,就表示这个方法是一个本地方法。换言之,就是不是使用java语言实现的方法。java在实现多线程时就使用了大量的本地方法,理由很简单java作为跨平台的语言,在与底层系统进行的交互的时候无法通过java语言实现,所以还是需要依靠例如C语言、C++语言来实现与底层的交互。同时这些语言的特性还能极大的提高java程序的运行效率。

使用
Java平台与主机平台的交互依靠的是JNI(Java Native Interface),即Java本地接口。
Java Code———>JNI————>C / C++ Code
演示一下调用本地方法的过程:
1、创建一个Java类,包含一个native方法和loadLibrary方法

public class FirstNative
{
    static
    {
        //加载类库
        System.loadLibrary("FirstNative");
    }
     //native函数
    public static native void sayHello();
     
    @SuppressWarnings("static-access")
    public static void main(String[] args)
    {
        new HelloNative().sayHello();
    }
}

直接运行之后出现报错信息

Exception in thread "main" java.lang.UnsatisfiedLinkError: no FirstNative in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
        at java.lang.Runtime.loadLibrary0(Runtime.java:870)
        at java.lang.System.loadLibrary(System.java:1122)
        at test.<clinit>(test.java:6)

表示找不到类,也难怪哦,我们自己写的类名,JVM怎么会知道呢。接下来创建它。

//编译源码
 javac FirstNative.java

 //生成头文件,有个小坑,就是-classpath参数是必须的,而且是绝对路径(到类文件所在的文件夹)。
javah -classpath F:\worksp\Javacode FirstNative

生成的.h文件,其中的头文件jni.h可以在%JAVA_HOME%/include中找到

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class FirstNative */

#ifndef _Included_FirstNative
#define _Included_FirstNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     FirstNative
 * Method:    Hello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_FirstNative_Hello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

根据头文件,来生成本地方法,使用C语言来实现。

#include "FirstNative.h"
#include <stdio.h>
 
JNIEXPORT void JNICALL Java_FirstNative_Hello
{
    printf("Hello,Native");    
}

生成DLL动态链接库,用java程序加载库,调用函数即可

gcc -m64  -Wl,--add-stdcall-alias -I"[JDK->include文件夹绝对路径]" -I"[JDK->include->win32文件夹绝对路径]" -shared -o [链接库名称] [C源码文件]

执行

java FirstNative

成功打印

Hello Native

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!