native关键字

native 用法

标记方法为原生函数,也即是这个函数是用C/C++语言实现的,并且被编译成了DLL或so文件,由java调用。
native Method: 一个java调用非java代码的接口
natvie 可以和除了abstract外的java标识符连用,native即表示这些方法有实现体,而abstract是表示方法无实现体,故不能一起用

native 特点

  • native 是用java和其他语言进行协作时使用,也就是native修饰的方法不是用java写的
  • native 的意思是通知操作系统 ,其具体行为由操作系统实现,java只能调用
  • java 是跨平台的语言,跨平台的同时牺牲了一些对底层的控制,但需要对底层操作时需要其他语言的帮助,此时就用到native
  • native 与其他java标志符连用时,其意义同非Native Method并无差别
  • 一个native method可以返回任何java类型,包括非基本类型,同样可以进行异常控制
  • JVM控制调用本地方法的所有细节
  • 含有本地方法的类,可以被继承,native方法可以在子类中被重写
  • 有了本地方法,java可以运行更底层的任务

JDK 那些部分有native方法

  • Object类
  • 并发包
  • 其他需要与操作系统接触的点

native 适用情况

  1. 为了底层的主机平台的某个特性,而这个特性JavaAPI无法访问
  2. 为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用Java编写的
  3. 为了加快程序的性能,将某个时间敏感方法来使用本地方法实现
  4. 与操作系统,某些硬件等交互信息

JNI

简介

  • JNI 即 Java Native Interface的缩写
  • JNI允许java与其他语言交互

Java与dll交互技术

  • JNI (只能C/C++实现)
  • jawin (基于JNI技术的win系统的应用库)
  • jacob (提供java调用microsoft的com对象)

实现方式

  • JNI对应用本身可看做是个代理模式
  • java程序是jvm通过加载并调用此jni程序来间接调用原生函数

JNI实现步骤

  1. 编写带用native声明的方法的java类,生成java类
  2. 用javac编译成class文件
  3. 使用javah -jni 类全限定名生成.h文件
  4. 使用c/c++实现本地方法,创建.h文件的实现
  5. 用gcc(或其他)编译成动态链接库,windows生成dll文件,linux下生成.so文件

JNI实现示例

windows下实现

  • java文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class HelloNative
    {
    static
    {
    System.loadLibrary("HelloNative");
    }

    public static native void sayHello();

    public static void main(String[] args)
    {
    new HelloNative().sayHello();
    }
    }
  • .h文件

jni.h 这个文件,在%JAVA_HOME%include

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: sayHello
* Signature: ()V
*/
//JNIENV: JNI Environment指针
// jclas 此Java代码中实例化的Java对象HelloNative的一个句柄
JNIEXPORT void JNICALL Java_HelloNative_sayHello
(JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif
  • 用c语言实现的具体实现

    1
    2
    3
    4
    5
    6
    #include "HelloNative.h"
    #include <stdio.h>
    JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *env, jclass jc)
    {
    printf("Hello,JNI");
    }
  • Windows执行以下命令:

gcc使用windows的TMD-GCC

1
2
3
4
5
6
7
8
9
10
11
javac HelloNative.java

javah HelloNative

gcc -m64 -Wl,--add-stdcall-alias -I"C:\Program Files\Java\jdk1.8.0_40\include" -I"C:\Program Files\Java\jdk1.8.0_40\include\win32" -shared -o HelloNative.dll HelloNative.c

将HelloNative.h 包含到环境变量
set PATH=%PATH%;当前目录

java HelloNative

Linux下实现

  • java .h .c代码一样

  • Linux执行以下命令

1
2
3
4
5
6
7
8
9
10
11
javac HelloNative.java

javah HelloNative

gcc -fPIC -D_REENTRANT -I/usr/lib/jvm/java-8-oracle/include -I/usr/lib/jvm/java-8-oracle/include/linux -c HelloNative.c

gcc -shared HelloNative.o -o libgoodluck.so

export LD_LIBRARY_PATH=`pwd`

java HelloNative

参考引用

链接:

http://blog.csdn.net/funneies/article/details/8949660
http://blog.csdn.net/jiakw_1981/article/details/3073613
http://blog.chinaunix.net/uid-20180960-id-1972669.html
http://www.cnblogs.com/Qian123/p/5702574.html#commentform
http://blog.csdn.net/tanga842428/article/details/52765978