一. 什么是Native Method
    简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。
     "A native method is a Java method whose implementation is provided by non-java code."
     在定义一个native method时,并不提供实现体(有些像定义一个java interface),因为其实现体是由非java语言在外面实现的。

  native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问

  JNI是Java本机接口(Java Native Interface),是一个本机编程接口,它是Java软件开发工具箱(Java Software Development Kit,SDK)的一部分。JNI允许Java代码使用以其他语言编写的代码和代码库。Invocation API(JNI的一部分)可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。

不过,对Java外部的调用通常不能移植到其他平台,在applet中还可能引发安全异常。实现本地代码将使您的Java应用程序无法通过100%纯Java测试。

但是,如果必须执行本地调用,则要考虑几个准则:

  1.将您的所有本地方法都封装到一个类中,这个类调用单个的DLL。对每一种目标操作系统平台,都可以用特定于适当平台的版本的DLL。这样可以将本地代码的影响减少到最小,并有助于将以后所需要的移植问题考虑在内。2.本地方法尽量简单。尽量使您的本地方法对第三方(包括Microsoft)运行时DLL的依赖减少到最小。使您的本地方法尽量独立,以将加载您的DLL和应用程序所需的开销减少到最小。如果需要运行时DLL,必须随应用程序一起提供。

下面给了一个示例:

package java.lang;
public class Object { ......public final native Class<?> getClass(); public native int hashCode(); protected native Object clone() throws CloneNotSupportedException; public final native void notify(); public final native void notifyAll(); public final native void wait(long timeout) throws InterruptedException; ......
} 

  标识符native可以与所有其它的java标识符连用,但是abstract除外。这是合理的,因为native暗示这些方法是有实现体的,只不过这些实现体是非java的,但是abstract却显然的指明这些方法无实现体。native与其它java标识符连用时,其意义同非Native Method并无差别。

一个native method方法可以返回任何java类型,包括非基本类型,而且同样可以进行异常控制。这些方法的实现体可以自制一个异常并且将其抛出,这一点与java的方法非常相似。
       native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法。JVM将控制调用本地方法的所有细节。

如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用java语言重写这个方法(这个似乎看起来有些奇怪),同样的如果一个本地方法被fianl标识,它被继承后不能被重写。
       本地方法非常有用,因为它有效地扩充了jvm.事实上,我们所写的java代码已经用到了本地方法,在sun的java的并发(多线程)的机制实现中,许多与操作系统的接触点都用到了本地方法,这使得java程序能够超越java运行时的界限。有了本地方法,java程序可以做任何应用层次的任务。

 二.为什么要使用Native Method
     java使用起来非常方便,然而有些层次的任务用java实现起来不容易,或者我们对程序的效率很在意时,问题就来了。

与java环境外交互:
     有时java应用需要与java外面的环境交互。这是本地方法存在的主要原因,你可以想想java需要与一些底层系统如操作系统或某些硬件交换信息时的情况。本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解java应用之外的繁琐的细节。

与操作系统交互:
     JVM支持着java语言本身和运行时库,它是java程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。然而不管怎样,它毕竟不是一个完整的系统,它经常依赖于一些底层(underneath在下面的)系统的支持。这些底层系统常常是强大的操作系统。通过使用本地方法,我们得以用java实现了jre的与底层系统的交互,甚至JVM的一些部分就是用C写的,还有,如果我们要使用一些java语言本身没有提供封装的操作系统的特性时,我们也需要使用本地方法。

Sun's Java
      Sun的解释器是用C实现的,这使得它能像一些普通的C一样与外部交互。jre大部分是用java实现的,它也通过一些本地方法与外界交互。例如:类java.lang.Thread 的 setPriority()方法是用java实现的,但是它实现调用的是该类里的本地方法setPriority0()。这个本地方法是用C实现的,并被植入JVM内部,在Windows 95的平台上,这个本地方法最终将调用Win32 SetPriority() API。这是一个本地方法的具体实现由JVM直接提供,更多的情况是本地方法由外部的动态链接库(external dynamic link library)提供,然后被JVM调用。

  

 三.JVM怎样使Native Method跑起来:
      我们知道,当一个类第一次被使用到时,这个类的字节码会被加载到内存,并且只会回载一次。在这个被加载的字节码的入口维持着一个该类所有方法描述符的list,这些方法描述符包含这样一些信息:方法代码存于何处,它有哪些参数,方法的描述符(public之类)等等。
      如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针。这些实现在一些DLL文件内,但是它们会被操作系统加载到java程序的地址空间。当一个带有本地方法的类被加载时,其相关的DLL并未被加载,因此指向方法实现的指针并不会被设置。当本地方法被调用之前,这些DLL才会被加载,这是通过调用java.system.loadLibrary()实现的。
  
     最后需要提示的是,使用本地方法是有开销的,它丧失了java的很多好处。如果别无选择,我们可以选择使用本地方法。

可以将native方法比作Java程序同C程序的接口,其实现步骤:

1、在Java中声明native()方法,然后编译(使用javac命令编译编写的Java类);
2、用javah产生一个.h文件(使用java -jni ****来生成后缀名为.h的头文件);
3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件)(使用其他语言(C、C++)实现本地方法);
4、将第三步的.cpp文件编译成动态链接库文件(将本地方法编写的文件生成动态链接库);
5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。

 以下是一个在Java中调用本地C程序的简单的例子:

a.编写HelloWorld.java类

class HelloWorld{public native void hello();static{System.loadLibrary("hello");}public static void main(String[] args){new HelloWorld().hello();}}

b.编译

    javac HelloWorld.java

c.生成.h文件

    javah -jni HelloWorld

生成内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloWorld */#ifndef _Included_HelloWorld#define _Included_HelloWorld#ifdef __cplusplusextern "C" {#endif/** Class:     HelloWorld* Method:    hello* Signature: ()V*/JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

第一个参数是调用JNI方法时使用的JNI Environment指针。

  第二个参数是指向在此Java代码中实例化的Java对象HelloWorld的一个句柄。其他参数是方法本身的参数

d.c实现

#include <jni.h>#include "HelloWorld.h"#include <stdio.h>JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *env,jobject obj){printf("Hello World!\n");return;}

其中,第一行是将jni.h文件引入(在%JAVA_HOME%\include目录下),里边有JNIEnv和jobject的定义。

e.编译c实现

这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成。
  

  cl -I%java_home%\include -I%java_home%\include\win32 -LD HelloWorldImp.c -Fehello.dll

  注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%\include -I%java_home%\include\win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。
  

f 运行程序
  

  java HelloWorld 就ok了!

其他查看http://www.ibm.com/developerworks/cn/java/jnimthds/了解详情

转载于:https://www.cnblogs.com/hwaggLee/p/4443097.html

java基础-关键字-native相关推荐

  1. JAVA基础——关键字与保留字——标识符——进制转换

    本节学习目录 前言 一.JAVA的关键字和保留字 1.什么是Java关键字? 2.什么是Java保留字? 二.JAVA标识符及命名规则 1.标识符 2.命名规则 三.进制的转换 1.何为进制? (1) ...

  2. java基础-关键字final

    概述 final是java中一个保留的关键字,也被视为一个修饰符(Modifier),可以修饰一个成员变量.方法参数.方法甚至一个类. final变量(域) 凡是用final关键字修饰的成员变量或本地 ...

  3. JAVA基础-关键字与保留字

    关键字的定义和特点: 定义:被JAVA预言赋予了特殊含义,用做专门用途的字符串(单词) 特点:关键字中所有字母都为小写字母 官方地址:https://docs.oracle.com/javase/tu ...

  4. java基础 - 关键字private、protected、default、public、final

    四种访问控制方式 关键字 范围 private 私用模式 本类 protected 保护模式 本类及子类 default(可不写) 默认包模式 包内 public 共用模式 任何地方 Final: 用 ...

  5. java基础提升篇:Java中Native关键字的作用

    初遇 初次遇见 native是在 java.lang.Object 源码中的一个hashCode方法: public native int hashCode(); 为什么有个native呢?这是我所要 ...

  6. JAVA基础之关键字、保留字和标识符

    关键字: 1.关键字(keyword)的定义和特点 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词) 特点:关键字中所有字母都为小写 官方地址: https://docs.oracle ...

  7. Java学习之路-----Java基础简介,基础语法,Java标识符,修饰符,关键字与注释

    这里写目录标题 Java简介 Java发展历程 Java语言平台版本 Java语言的特点 Java语言跨平台原理--JVM JRE和JDK JDK安装路径下的目录解释 Java基础语法 Java标识符 ...

  8. -1-1 java 基础语法 java关键字 java 注释 常量 语句 运算符 函数 数组定义

    Java语言基础组成 关键字 标识符 注释 常量和变量 运算符 语句 函数 数组 关键字 定义:被Java语言赋予了特殊含义的单词 特点:关键字中所有字母都为小写 用于定义数据类型的关键字 class ...

  9. JAVA基础入门(4)—— 标识符、关键字和字面值

    前言 在上一节中,讲到了JAVA开端的一个HelloWorld小程序,其中对代码以及一些细节的知识点做了阐述.本节将继续对JAVA基础入门知识进行讲解演示,分别对JAVA中的标识符.关键字以及字面值进 ...

最新文章

  1. 与Andrey Breslav谈论Kotlin 1.0的发布
  2. PyTorch 实现孪生网络识别面部相似度
  3. InnoDB和MyISAM引擎的效率比较
  4. springmvc二十八:springmvc使用common-fileUpload实现文件上传
  5. nylgacm_1057_寻找最大数(三)
  6. 考研计算机网课辅导,考研计算机网课辅导哪个好
  7. OI树上问题 简单学习笔记
  8. 编译原理的first、follow、select
  9. 计算机网络课程设计 学校园网设计
  10. 医学诊断报告生成论文综述
  11. 超好用的卸载工具——geek
  12. php搭建简单表格的制作方法,最简单的表格制作方法技巧
  13. 如何利用pygame 开发坦克大战小游戏
  14. 一文详解什么是代理模式
  15. Android实用视图动画及工具系列之六:通用表情栏,仿QQ微信聊天弹出表情选框
  16. dell 服务器引导盘安装2003
  17. js_中国大陆加港澳台手机正则验证
  18. fabs linux头文件,C/C++ algorithm头文件的max()、min()、abs()和math头文件的fabs(
  19. 百度地图使用,以及一些api
  20. xss基础认证钓鱼代码收集

热门文章

  1. mysql查询全年星期_数据库查询显示一年中所有的周一到周五的数据
  2. Opencv--findHomography 与 getPerspectiveTransform异同
  3. OpenCV将单通道的Mat转换为三通道的Mat
  4. 设置环境变量的三种方法【转载】
  5. CV之Harris特征点检测器-兴趣点检测(详解)
  6. 读《写给大家看的设计书》
  7. python 聚类_聚类算法中的四种距离及其python实现
  8. ajax高效分页查询,基于 Jquery+Ajax+Json高效分页实现代码
  9. 第三章计算机网络,第三章-计算机网络及应用.ppt
  10. excel 字符串拼接_Excel教程:应收账款自动弹窗提醒