文档章节

Java中Native关键字的作用

pioneerDev
 pioneerDev
发布于 2017/04/28 11:55
字数 1319
阅读 3
收藏 0

阅读目录

初次遇见 native是在 java.lang.Object 源码中的一个hashCode方法:

1

public native int hashCode();

为什么有个native呢?这是我所要学习的地方。所以下面想要总结下native。

一、认识 native 即 JNI,Java Native Interface

凡是一种语言,都希望是纯。比如解决某一个方案都喜欢就单单这个语言来写即可。Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。

二、用 Java 调用 C 的“Hello,JNI”

我们需要按照下班方便的步骤进行:

1、创建一个Java类,里面包含着一个 native 的方法和加载库的方法 loadLibrary。HelloNative.java 代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public class HelloNative

{

    static

    {

        System.loadLibrary("HelloNative");

    }

     

    public static native void sayHello();

     

    @SuppressWarnings("static-access")

    public static void main(String[] args)

    {

        new HelloNative().sayHello();

    }

}

首先让大家注意的是native方法,那个加载库的到后面也起作用。native 关键字告诉编译器(其实是JVM)调用的是该方法在外部定义,这里指的是C。如果大家直接运行这个代码,  JVM会告之:“A Java Exception has occurred.”控制台输出如下:

1

2

3

4

5

Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path

    at java.lang.ClassLoader.loadLibrary(Unknown Source)

    at java.lang.Runtime.loadLibrary0(Unknown Source)

    at java.lang.System.loadLibrary(Unknown Source)

    at HelloNative.<clinit>(HelloNative.java:5)

这是程序使用它的时候,虚拟机说不知道如何找到sayHello。下面既可以手动写,自然泥瓦匠是用

    2、运行javah,得到包含该方法的C声明头文件.h

将HelloNative.java ,简单地 javac javah,如图

 

就得到了下面的 HelloNative.h文件 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/* 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

 */

JNIEXPORT void JNICALL Java_HelloNative_sayHello

  (JNIEnv *, jclass);

 

#ifdef __cplusplus

}

#endif

#endif

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

3、根据头文件,写C实现本地方法

这里我们简单地实现这个sayHello方法如下:

1

2

3

4

5

6

7

#include "HelloNative.h"

#include <stdio.h>

 

JNIEXPORT void JNICALL Java_HelloNative_sayHello

{

    printf("Hello,JNI");   

}

4、生成dll共享库,然后Java程序load库,调用即可。

在Windows上,MinGW GCC 运行如下

1

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

-m64表示生成dll库是64位的。然后运行 HelloNative:

1

java HelloNative

 

终于成功地可以看到控制台打印如下:

1

Hello,JNI

三、JNI 调用 C 流程图

回到顶部

四、其他介绍

native是与C++联合开发的时候用的!java自己开发不用的!


使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。
这些函数的实现体在DLL中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。


1。native 是用做java 和其他语言(如c++)进行协作时用的
也就是native 后的函数的实现不是用java写的
2。既然都不是java,那就别管它的源代码了,呵呵


native的意思就是通知操作系统,
这个函数你必须给我实现,因为我要使用。
所以native关键字的函数都是操作系统实现的,
java只能调用。


java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了

Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能。
  可以将native方法比作Java程序同C程序的接口,其实现步骤:
  1、在Java中声明native()方法,然后编译;
  2、用javah产生一个.h文件;
  3、写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
  4、将第三步的.cpp文件编译成动态链接库文件;
  5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。


JAVA本地方法适用的情况 
1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问

2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的

3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。

本文转载自:http://www.cnblogs.com/Qian123/p/5702574.html

共有 人打赏支持
pioneerDev
粉丝 3
博文 23
码字总数 4224
作品 0
青岛
程序员
私信 提问
Java学习资料-标识符、关键字

1、标识符 (1)Java对各种变量、方法和类等要素命名时使用的字符序列称为标识符。凡是自己可以起名字的地方都叫标识符,都遵守标识符的规则。 (2)Java标识符命名规则: 标识符由字母、下划...

晓阳
2015/01/05
0
0
native关键字初识--java调用非java代码的接口

Java基础知识——JNI入门介绍(上) Java™ 本机接口(Java Native Interface,JNI)是一个标准的 Java API,它支持将 Java 代码与使用其他编程语言编写的代码相集成。如果您希望利用已有的代...

成长中的菜鸟
2015/02/10
0
0
Java JNI介绍

Java jni本意是Java native interface(Java本地接口),是为了方便Java调用c、c++等本地代码所封 装的一层接口。大家都知道,Java的优点是跨平台,但是作为优点的同时,其在本地交互的时候就...

长平狐
2013/12/25
114
0
Android 8.1 源码_核心篇(一) -- 深入研究 JNI

开篇 核心源码 关键类 路径 MediaScanner.java frameworks/base/media/java/android/media/MediaScanner.java androidmediaMediaScanner.cpp frameworks/base/media/jni/androidmediaMediaS......

DeepCoder_Marco
2018/08/28
0
0
构造函数、构造代码块、this关键字

构造函数、构造代码块、this关键字 一、构造函数 1.构造函数的作用 给对应的对象进行初始化。 2.构造函数的定义格式 3.构造函数要注意的细节 构造函数是没有返回值类型的。 构造函数的函数名...

JS_HCX
2018/12/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day11

architect刘源源
41分钟前
3
0
论学好Linux系统的超级重要性

不知道各位在日常的工作生活中有没有接触过“rm -rf /*”这个命令,因为这个命令搞出来的事情可还不少呢!前段时间就在一个群里看到了有个小伙子,老板让他去维护一下服务器,这小伙也不太懂...

Linux就该这么学
昨天
1
0
git 使用

1,首先在github配置好信息和仓库,然后在本地进行操作 git init git config user.name 'zhangwuer' git config user.email '56789053@qq.com' 2,与远程分支建立连接 git checkout -b test......

天王盖地虎626
昨天
3
0
git checkout 命令详解

在日常的git操作中,git checkout——检出,是我们的常用命令。最为常用的两种情形是创建分支和切换分支。 在下面的命令中,使用了一些简写,在这里说明一下: git st # git statusgit ci ...

shzwork
昨天
8
0
【Nginx】Nginx多级代理,获取客户端真实请求IP以及每级代理IP

Nginx多级代理,获取客户端真实请求IP以及每级代理IP 如图所示,每一级nginx里的location配置里需要加上对应的配置,最后一级nginx是直接到应用,测试时为了方便,直接用echo模块去测试,打印...

薛定谔的旺
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部