今天一不小心跟进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 helloworld
javah 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 __cplusplus
extern "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/535a3131ccd8, 安装成功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是无法直接操作内存的。

【作者简介】

秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。

此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者核实删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~

native关键字是干什么的?的更多相关文章

  1. Java中native关键字

    Java中native关键字 标签: Java 2016-08-17 11:44 54551人阅读 评论(0) 顶(23453) 收藏(33546)   今日在hibernate源代码中遇到了nati ...

  2. Java中Native关键字的作用

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

  3. Java native关键字

    在String类中 public native String intern(); native关键字是干嘛的? Java不是完美的,Java的不足除了体现在运行速度上要比传统的C++慢许多之外,Jav ...

  4. Java的native关键字---JAVA下调用其他语言的关键词

    今天研究Java基础类库,Object类的时候,发现了一个关键字:native 咦?这是个什么东东?它认识我,我可不认识它! 嘿嘿,没关系,baidu一下. java native关键字 一. 什么是 ...

  5. Java中的native关键字与JNI

    一.先说一下大致的意思: jdk提供的类库源代码中有一些方法没有实现,这些方法前有native关键字,如object类中的 : native Object clone() throws CloneNo ...

  6. Java中native关键字[转]

    原文链接:http://blog.163.com/yueyemaitian@126/blog/static/21475796200701491621267/ 今日在hibernate源代码中遇到了na ...

  7. java中被遗忘的native关键字

    我是无意间看见JNI( java调用动态链接库dll )这块的东西. 所有记下来:本地声明方法  装载完成dll文件后,将使用的方法用native关键字声明. public native static ...

  8. native关键字(本地方法)、 java调用so动态链接库

    Java native关键字 一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个ja ...

  9. java中native关键字的用法

    前言: 如果阅读过JDK的源码,我们会发现Thread.java类里有一个方法比较特殊 private native void start0(); 概念: native关键字说明其修饰的方法是一个原生 ...

随机推荐

  1. SpringBoot+JPA+SpringSeurity+JWT

    目的:使用这个框架主要就是为了解决高并发环境下登陆操作对数据库及服务器的压力,同时能保证安全性: 加载时,SpringSecurity定义拦截器和添加两个Fitler: 登陆时,登陆成功,通过传入的信 ...

  2. 使用阿里云镜像仓库构建国外 Docker 镜像

    使用阿里云镜像仓库下载国外镜像 在日常使用 Docker 或 K8S 的过程中,经常会需要到国外的网站中下载镜像,但是有些网站在国内是无法访问的.对于这个问题可以使用阿里云提供的镜像仓库进行下载,然后 ...

  3. OpenCascade拓扑对象之:拓扑对象的层次结构

    @font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...

  4. 华为云FusionInsight MRS:助力企业构建“一企一湖,一城一湖”

    摘要:华为云FusionInsight MRS新一代的数据湖,让大数据越用越快.越用越易.越用越稳.越用越省!让数据价值近在眼前! 10月30日,以"携手共赢·数创未来"为主题的第 ...

  5. 水题挑战2 :NOIP提高组 2011 聪明的质监员

    小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从\(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) 以及价值 \(v_i\) .检验矿 ...

  6. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

  7. Go读取论文并转换为simhahs

    package main import ( "fmt" _"flag" _ "os" _ "io/ioutil" _&q ...

  8. hadoop之yarn(优化篇)

    最近一直在学习hadoop的一些原理和优化,然后也做了一些实践,也有没有去做实践的,反正个人观点都记录下来 一.yarn的介绍 YARN的基本结构由一个ResourceManager与多个NodeMa ...

  9. 内网渗透 day11-免杀框架

    免杀框架 目录 1. venom框架 2. shelltel框架 3. backdoor factory(BDP) 1. venom框架 cd venom进入venom文件夹中./venom.sh进入 ...

  10. waitpid()系统调用学习

    waitpid()的头文件 #include <sys/types.h>  #include <sys/wait.h> pid_t waitpid(pid_t pid,int ...