本地方法

原创 2007年10月04日 10:21:00

java本地方法

用native修饰符修饰的方法是本地方法。native修饰符一般用来声明用其他语言书写方法体、并具体实现方法功能的特殊方法。这里的其他语言包括C、C++、Fortran、汇编语言等。由于native方法的方法体是用其他语言在程序外部写成,所以所有的native方法都没有方法体,而用一个分号代替。
  为了支持native方法,Java提供了JNI软件工具,JNI是Java Native Interface的缩写。从Java 1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
  用其他语言编写类方法的目的在于:充分利用已存在的程序功能模块,并避免重复工作。由于Java是解释型语言,它的运行速度不可能很快。在某些实时性比较强或执行效率要求比较高的场合,就可以利用native方法来求助于其他运行速度较高的语言。
  下面我们以一个例子,说明如何使用其他语言编写的程序,这里以C语言为例。

(1)编写java程序,在java程序中加入本地方法说明:

  public native void 方法名();

不妨仍然使用HelloWorld,如下所示。

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

这部分内容是选学内容,读者可以略去不看。
  在程序中,声明了一个displayHelloWorld的native方法,它是一个空方法;还利用静态初始化器加载了一个动态库(System.loadLibrary("hello");)。因为方法displayHelloWorld()并没有实现,但是在下面在main方法中就直接使用了,所以必须在使用前对它进行初始化。加载动态库就是实现这个目的,“hello”是动态库的名字。

(2)编译程序:

  javac HelloWorld.java

(3)生成扩展名为.h的头文件:

  javah –jni 类名

这里是:

  javah -jni HelloWorld

其中头文件HelloWorld.h的内容如下:

  /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class:   HelloWorld * Method:  displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif

可以这样理解:这个.h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。

(4)编写本地方法,实现和由javah命令生成的头文件里面声明的方法名相同的方法。本地方法在C语言中的方法名为:

  Java_ClassName _methodName (JNIEnv *env, jobject obj,……)

代码如下:

  #include "jni.h" #include "HelloWorld.h" #include JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!/n"); return; }

注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入。然后保存为HelloWorldImpl.c就可以了。

(5)将头文件和(本地方法)实现文件编译成共享库文件,生成动态库。
  这里以在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文件。

(6)运行程序即可:

  java HelloWorld

 
版权声明:本文为博主原创文章,未经博主允许不得转载。

1.1本地方法栈

[last updated :2016/2/8]     在上一讲(1. JVM运行时数据区)Topic 1中简略谈到本地方法栈。本文将通过以下几个话题来进一步讨论本地方法栈。 Topic 1....
  • xiangliqu
  • xiangliqu
  • 2016年02月08日 22:49
  • 2429

浅谈Java的本地方法

浅谈Java和C的混合编程
  • Jack_Lantern
  • Jack_Lantern
  • 2016年10月07日 23:05
  • 1238

JAVA本地方法详解,什么是JAVA本地方法?

前言: JAVA中有两种方法:JAVA方法和本地方法 JAVA方法是由JAVA编写的,编译成字节码,存储在class文件中 本地方法是由其它语言编写的,编译成和处理器相关的机器代码 本地方法保存...
  • wi__wi
  • wi__wi
  • 2016年04月07日 14:49
  • 501

本地方法栈

本地方法栈(Native Method Stack) 与虚拟机栈所发挥的作用非常相似,它们的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方...
  • Petershusheng
  • Petershusheng
  • 2016年10月09日 21:32
  • 1063

虚拟机栈与本地方法栈

栈区: 栈中分配的是基本类型和自定义对象的引用。每个线程包含一个栈区,栈中只保存基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈...
  • weixin_38070406
  • weixin_38070406
  • 2017年09月02日 21:02
  • 145

java内存区域-本地方法栈

本地方法栈与虚拟机栈发挥的功能非常类似,只是虚拟机栈为虚拟机执行java方法而服务,而本地方法栈为虚拟机执行native方法而服务。虚拟机规范中对本地方法栈中使用的方法的语言、使用方式、与数据结构并没...
  • YChenFeng
  • YChenFeng
  • 2017年08月17日 10:45
  • 372

JVM学习笔记(一)——本地方法栈及native方法

最近开始看《深入理解Java虚拟机》,确实是本宝书。 看到虚拟机栈和本地方法栈的区别的时候有点疑惑,因为本地方法栈为虚拟机的Native方法服务。以下转载一篇关于native方法的介绍: http:/...
  • qq_28885149
  • qq_28885149
  • 2016年09月26日 18:01
  • 3568

Java调用本地方法又是怎么一回事

JNIJNI即Java Native Interface,它能在Java层实现对本地方法的调用,一般本地的实现语言主要是C/C++,其实从虚拟机层面来看JNI挺好理解,JVM主要使用C/C++ 和少量...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2017年07月10日 17:28
  • 2505

JVM中的本地方法栈(Native Method Stacks)和Java虚拟机栈(Java Virtual Machine Stacks)

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native...
  • uk8692
  • uk8692
  • 2016年02月17日 14:19
  • 1639

JVM 内存基础概念之程序计数器与 Java 虚拟机栈和本地方法栈

前言 在上篇文章中,我们了解到 JVM 运行时数据区有五个区域,分别是:程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区。在这篇文章中,我们就来了解下程序计数器与 Java 虚拟...
  • Airsaid
  • Airsaid
  • 2016年02月01日 17:10
  • 1705
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:本地方法
举报原因:
原因补充:

(最多只允许输入30个字)