Java中Native关键字的作用
初次遇见 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 __cplusplusextern "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.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
Java中Native关键字的作用的更多相关文章
- 【Java_基础】Java中Native关键字的作用
本篇博文转载与:Java中Native关键字的作用
- Java中native关键字
Java中native关键字 标签: Java 2016-08-17 11:44 54551人阅读 评论(0) 顶(23453) 收藏(33546) 今日在hibernate源代码中遇到了nati ...
- java中static关键字的作用
java中static关键字主要有两种作用: 第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关. 第二,实现某个方法或属性与类而不是对象关联在一起 简单来说,在Java语言中,s ...
- Java中native关键字[转]
原文链接:http://blog.163.com/yueyemaitian@126/blog/static/21475796200701491621267/ 今日在hibernate源代码中遇到了na ...
- java中final 关键字的作用
final 关键字的作用 java中的final关键字可以用来声明成员变量.本地变量.类.方法,并且经常和static一起使用声明常量. final关键字的含义: final在Java中是一个保留的关 ...
- java中native关键字的用法
前言: 如果阅读过JDK的源码,我们会发现Thread.java类里有一个方法比较特殊 private native void start0(); 概念: native关键字说明其修饰的方法是一个原生 ...
- Java中volatile关键字及其作用是什么?
在 Java 多线程中如何保证线程的安全性?那我们可以使用 Synchronized 同步锁来给需要多个线程访问的代码块加锁以保证线程安全性.使用 synchronized 虽然可以解决多线程安全问题 ...
- Java 中 volatile 关键字及其作用
引言 作为 Java 初学者,几乎从未使用过 volatile 关键字.但是,在面试过程中,volatile 关键字以及其作用还是经常被面试官问及.这里给各位童靴讲解一下 volatile 关键字的作 ...
- java中transient关键字的作用
Java有个特点就是序列化,简单地来说就是可以将这个类存储在物理空间(当然还是以文件的形式存在),那么当你从本地还原这个文件时,你可以将它转换为它本身.这可以极大地方便网络上的一些操作,但同时,因为涉 ...
随机推荐
- Android LruCache(Picasso内存缓存)
Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部,当cache已满的时候加入新的item时,在队列尾部的item会被回收. 如果你cache的某个值需要 ...
- Codeforces Testing Round #10 B. Balancer
水题,只要遍历一遍,不够平均数的,从后面的借,比平均数多的,把多余的数添加到后面即可,注意数据范围 #include <iostream> #include <vector> ...
- Codeforces Round #251 (Div. 2) A - Devu, the Singer and Churu, the Joker
水题 #include <iostream> #include <vector> #include <algorithm> using namespace std; ...
- UIView 的属性opaque详解
该属性用法决定与该消息的接受者是否让其视图透明. 该属性的用处在于:给绘图系统提供一个性能优化开关. 当该值设计为YES,那么绘图系统会把它当作不透明看待,那么在执行绘图的时候会优化绘图一些操作,并且 ...
- Windows环境下的NodeJS+NPM+Bower安装配置步骤
Windows下的NodeJS安装是比较方便的(v0.6.0版本之后,支持windows native),只需要登陆官网(http://nodejs.org/),便可以看到首页的“INSTALL”按钮 ...
- js实现事件模型bind与trigger
function Emitter() { this._listener = [];//_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2] } //注册事件 Em ...
- mvn install
mvn install:install-file \ -DgroupId=com.weibo.datasys.weistreamng \ -DartifactId=weistreamng-092-fr ...
- js流程控制语句
do...while语句 do...while语句是一种先运行,后判断的循环语句.也就是说,不管条件是否满足,至少先运行一次循环体. var box = 1; ...
- phpwind < v6 版本命令执行漏洞
phpwind/sort.php 会定期每天处理一次帖子的浏览量.回复量.精华版排序 代码直接使用savearray将数据库查询出来的内容写入php文件,savearray出来的参数,都使用" ...
- UIBezierPath 的使用
使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中.此类是Core Graphics框架关于path的一个封装.使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线 ...