Java--native关键字

  • native是与C++联合开发的时候用的!java自己开发不用的!
  • 使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。 这些函数的实现体在DLL中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。
  • native的意思就是通知操作系统, 这个函数你必须给我实现,因为我要使用。 所以native关键字的函数都是操作系统实现的, java只能调用。
  • java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了
  1. 汇编生c,c生万物,其实java要实现对底层的控制,还是需要c/c++帮忙,老大毕竟是老大。
  2. native关键字我们开发应用的时候是用不到的,那什么时候用到呢?那些开发java语言的时候用到,native关键字是与c++联合开发的时候使用的,要不java控制不了底层啊,比如内存。所以还是那句:汇编生c,c生万物,c++是c的升级版。
  3. 这是java调用其他地方的接口的一个声明关键字,意思是这个方法不是java实现的,有挺多的编程语言都有这样的特性,比如c++里面使用extern "c"来表示告诉c++编译器去调用c里面已经实现好的函数,而不是自己去实现。native方法有点像java 里面的interface,都不用去实现,而是有别人去实现,但是interface是谁实现接口谁实现,native方法是直接交给c/c++来实现。java只能调用,由操作系统实现。
  4. native方法不能与abstract方法一起使用,因为native表示这些方法是有实现体的,但是abstract却表示这些方法是没有实现体的,那么两者矛盾,肯定也不能一起使用。 

java是通过什么来调用到外部的代码的呢? 

上面说native表示这个方法不是java实现的,那么就不是原生态方法,也就不会存在这个文件中,而是存在其他地方,那么java要怎么调用才能调用到呢? 

  • JNI(Java Native Interface)这是一个本机编程的接口,它也是java jdk(开发工具包)的一部分,JNI可以支持java中使用其他语言,java要调用其他语言的接口,需要经过他处理。java所谓的跨平台,在一定程度上放弃了底层操作,因为不同的硬件或者操作系统底层的操作都是不一样的。

                      

那么我们现在来写一个程序:helloWorld.java

public class helloworld{
  static
  {
    System.loadLibrary("cSayHello");
  }
  public static native void hello();
  @SuppressWarnings("static-access")
  public static void main(String[] args){
    new helloworld().hello();
  }
}

直接在编译器运行这段代码会出现下面错误:

            

上面的错误是说找不到cSayHello:no cSayHello in java.library.path,所以啊,这个c/c++的方法我们要自己实现,毕竟我们用的不是操作系统以及定义好的方法。 
所以我们先来,使用cmd**在helloworld.java所在的目录下**使用命令行:

javac helloworld
javah helloworld

                  

然后我们可以看到在helloworld.java所在的目录下多了两个文件,一个是helloworld.class文件,一个是helloworld.h文件。 
打开helloworld.h,里面引用了jni.h这个文件,这个文件在我们安装的java目录下面的include文件下:

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

#ifndef _Included_helloworld
#define _Included_helloworld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     helloworld
 * Method:    hello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_helloworld_hello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

 我们来写需要引入的c文件cSayHello,同一个文件夹就可以。

#include "helloworld.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_helloworld_hello(JNIEnv *env, jclass jc)
{
    printf("Hello,I use JNICALL");    
}

然后直接运行,就可以看到输出了

java helloworld

小结:

在java中使用native的步骤: 

  1. 在java代码中声明native方法 
  2. 执行javah来生成一个.h文件 
  3. 写.cpp文件来实现native导出的方法,需要包含上面第二步产生的.h文件,同时也包含了jdk自带的jni.h 
  4. 将第三步的.cpp文件通过gcc 编译成动态链接库文件 
  5. 在java中使用的用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问 
  6. 一般情况下,我们jdk中声明的native方法,在编译的时候都会自动去加载动态链接库文件,而不需要我们自己去操作了。

 参考博文:

https://blog.csdn.net/youjianbo_han_87/article/details/2586375

https://blog.csdn.net/Aphysia/article/details/80593654

猜你喜欢

转载自blog.csdn.net/weixin_44371151/article/details/88567705