[TOC]
明天一不小心跟进Object的源码中,发现一个native
关键字,一脸蒙蔽,怎么我素来没有用过。
// 这是计算对象的hsahcode的办法,波及到内存地址public native int hashCode();
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
却示意这些办法是没有实现体的,那么两者矛盾,必定也不能一起应用。
1.怎么调用到native办法的呢?
下面说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 helloworldjavah 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 __cplusplusextern "C" {#endif/* * Class: helloworld * Method: hello * Signature: ()V */JNIEXPORT void JNICALL Java_helloworld_hello (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif
我的java
是装在D盘
上面:
咱们来写须要引入的c
文件cSayHello
,我也是放在桌面,反正同一个文件夹就能够。
#include "helloworld.h"#include <stdio.h> JNIEXPORT void JNICALL Java_helloworld_hello(JNIEnv *env, jclass jc){ printf("java helloworld"); }
在windows
零碎上,须要下载安装WinGW Gcc
,装置教程参考https://www.jianshu.com/p/535... 装置胜利cmd
输出:
gcc -m64 -Wl,--add-stdcall-alias -I"D:\Java\jdk1.8.0_111\include" -I"D:\Java\jdk1.8.0_111\include\win32" -shared -o cSayHello.dll helloworld.c
而后间接运行,就能够看到输入了
java helloworld
2. java调用自定义native办法步骤
在java中应用native的步骤:
1.在java代码中申明native办法
2.执行javah来生成一个.h文件
3.写.cpp文件来实现native导出的办法,须要蕴含下面第二步产生的.h文件,同时也蕴含了jdk自带的jni.h
4.将第三步的.cpp文件通过gcc 编译成动态链接库文件
5.在java中应用的用System.loadLibrary()办法加载第四步产生的动态链接库文件,这个native()办法就能够在Java中被拜访
个别状况下,咱们jdk中申明的native办法,在编译的时候都会主动去加载动态链接库文件,而不须要咱们本人去操作了。
3.应用native的毛病
应用native的毛病:可移植性差,把对底层的控制权交给其余语言,那么也会呈现不稳定性,庆幸的是当初操作系统的底层实现根本不会扭转。下面hsahcode()的计算真是通过内存所在的内存块来计算的,java是无奈间接操作内存的。
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使迟缓,驰而不息。这个世界心愿所有都很快,更快,然而我心愿本人能走好每一步,写好每一篇文章,期待和你们一起交换。
此文章仅代表本人(本菜鸟)学习积攒记录,或者学习笔记,如有侵权,请分割作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有谬误之处,还望指出,感激不尽~