java源码分析-native方法的调用

2023-11-03

java源码分析-native方法的调用

​ 这段时间在分析java源码时,经常能看到很多的底层源码中都调用了被native关键字修饰的方法,也就是java调用本地方法。但是在进行debug时有进不去,看不了具体的实现。因为这写方法是用c/c++实现的,那么这对我们分析源码就有了很多的阻碍,这些方法就像黑盒一样。于是我就在想,java是怎么调用这些本地方法的呢?接下来我们就一步步的探究一下这其中的原理。

那么这一篇我们就来自己来通过java实现native方法的调用。

1.什么是native方法

​ native是java的关键字,用来标识某个方法为本地方法。我们知道java语言的执行是依赖于java虚拟机的,java文件被编译成能够被java虚拟机识别并执行的字节码文件,java虚拟机根据字节码文件中的命令调用操作系统相关指令,完成相关的功能。所有java语言无法直接操作操作系统指令,中间隔了一层JVM。但是c/c++这类高级语言却可以直接与操作系统打交道。于是乎就产生了这样的想法:java通过调用c/c++的方式来完成相应的与操作系统相关的底层动作,这其实就是JNI(java native interface)技术。

2.简单的JNI案例

我们的操作环境是给予Linux系统。

2.1简单的java类

/**
 * java JNI 技术
 * 模拟java调用C
 */
public class JNIDemo {
    {
        //系统加载其他语言的函数
        System.load("/home/sj/jni/test/cJNI.so");
    }

    //native标识本地方法
    public native void helloJNI();

    public static void main(String[] args) {
        new JNIDemo().helloJNI();
    }
}

将java文件上传至linux系统/home/sj/jni/test。

2.2编译获取字节码文件

直接在改路径下通过java编译命令生成字节码文件。

java JNIDemo.java

这样该路径下就会生成.class字节码文件:
在这里插入图片描述

2.3javah命令

在该路径下使用javah命令生成头文件。

javah JNIDemo

执行后生成,会生成JNIDemo.h文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sXOqDt4w-1612182247998)(C:\Users\viruser.v-desktop\AppData\Roaming\Typora\typora-user-images\image-20210201190624806.png)]

可以看一下这个文件,vim打开:

#include <jni.h>
/* Header for class JNIDemo */

#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JNIDemo
 * Method:    helloJNI
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNIDemo_helloJNI	# 这里就是java文件中cMethod方法的签名。
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

JNIEXPORT void JNICALL Java_JNIDemo_helloJNI 这句需要我们关注,因为后面的c语言实现的方法必须“Java_JNIDemo_helloJNI”一致。

2.4用C写一个native方法

下面我们模拟一个C方法:

vim cjni.c
#include <stdio.h> //头文件
#include "JNIDemo.h" // java文件头,这里一定要加上上面java语言的头文件

// 这就是上面头文件中的cMethod方法的具体实现,注意方法签名不能变,一定要和头文件一样。
JNIEXPORT void JNICALL Java_JNIDemo_helloJNI(JNIEnv *env, jobject c1)
{
    // 如果java调用cMethod方法成功,则会打印这句话
    printf("hello jni! success ! \n");
}

下面使用cjni.c生成动态链接库文件:cJNI.so

gcc  -fPIC -I /opt/jdk1.8.0_211/include  -I /opt/jdk1.8.0_211/include/linux   -shared -o cJNI.so cjni.c

/opt/jdk1.8.0_211/include和/opt/jdk1.8.0_211/include/linux分别是linux系统安装jdk源码路径;

注意生成的动态链接库文件名称cJNI.so要与一开始的java代码中System.load("/home/sj/jni/test/cJNI.so");对应。

这样该路径下就有如下的五个文件了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16Dp61Du-1612182248001)(C:\Users\viruser.v-desktop\AppData\Roaming\Typora\typora-user-images\image-20210128213052269.png)]

2.5完成调用

完成以上操作,就可以执行我们的java代码,完成调用了:

java JNIDemo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yS4YUNc7-1612182248005)(C:\Users\viruser.v-desktop\AppData\Roaming\Typora\typora-user-images\image-20210201192209791.png)]

通过执行打印的结果hello jni! success !可以看出,java调用到了native方法,并执行了C文件中的方法体,并打印出执行成功。

简单总结一下JNI的调用过程:

第一,通过System.loadLibrary()将包含本地方法实现的动态文件加载进内存;

第二,当Java程序需要调用本地方法时,虚拟机在加载的动态文件中定位并链接该本地方法,从而得以执行本地方法。

3.JNI的使用场景

3.1解决性能问题

当程序对时间或者性能要求特别高时,就可能需要使用底层语言,例如使用C或者C++来执行相关功能,这时候就可以通过使用java语言来调用C/C++来完成个需求了。

3.2本地方法调用问题

​ JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。

3.3嵌入式开发

​ 正是由于JNI解决了本机平台接口调用问题,于是JNI在嵌入式开发领域也是如火如荼。

3.小结

​ JNI计数可以帮助我们解决跨语言调用问题,主要解决java语言调用C/C++语言的过程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java源码分析-native方法的调用 的相关文章

  • jdk安装与环境变量配置,看这篇就够了

    文章目录 场景 jdk 下载安装 如何环境变量的配置 总结 场景 在做 java 开发或者 android 开发 经常会碰到 jdk 安装与环境变量的配置 每次配置的时候 经常需要去查看一下 而且偶尔还会出现错误 这里就把这块详细的记录一下
  • 深入详解ThreadLocal内存泄漏问题

    1 造成内存泄漏的原因 threadLocal是为了解决对象不能被多线程共享访问的问题 通过threadLocal set方法将对象实例保存在每个线程自己所拥有的threadLocalMap中 这样每个线程使用自己的对象实例 彼此不会影响达
  • 阿里云—(1)安装JDK 11

    1 查看原有JDK版本 若新装系统 可忽略 yum list installed grep java 如图所示 代表已安装 2 查看yum库内所有的JDK版本 yum y list java 当你已经安装了某个版本后 显示的为本地安装包 下
  • 在Ubuntu系统安装jdk1.7步骤

    在Ubuntu12 04系统安装sun jdk1 7 可以到 http www oracle com 下载jdk1 7版本 选择平台Linux x64 Accept the license agreement and download th
  • Java SE 16 record 类型说明与使用

    Java SE 16 record 类型说明与使用 作者 Grey 原文地址 博客园 Java SE 16 record 类型说明与使用 CSDN Java SE 16 record 类型说明与使用 说明 record 是 Java SE
  • [小白进阶日记]JDK12 ZIP版配置教程

    JDK12 ZIP版配置教程 JDK 12 ZIP版配置教程 JDK 12 ZIP版配置教程 JKD下载地址 https download csdn net download qq 41684083 11472693 1 首先解压压缩包 2
  • Linux下jdk的下载安装

    将jdk放到Linux中 由于jdk现在不好下载了 所以笔者通过网上查找合适的资源之久 直接上传到服务器上 解压 进入jdk所在目录键入下面的命令进行解压 tar zxvf jdk 8u241 linux x64 tar gz 如下图所示
  • android studio设置jdk版本项目设置和全局设置(保姆级图文)

    步骤 系列文章 方法1 修改项目的gradle构建jdk 建议在使用别人的单个项目时使用 方法2 修改所有项目的gradle构建jdk 自己的项目使用 全局项目应用 总结 系列文章 提示 转到安卓学习专栏 观看更多内容 点我直达 gt 安卓
  • idea运行项目报错Cannot run program “C:\Program Files\Java\jdk1.8.0_121\bin\java.exe......解决办法

    在环境变量都配置完好的情况下 基本就是idea的配置除了问题可以检查以下几点 1 SDKs检查 2 路径检查 3 项目配置检查
  • 将 Tocmat5.0 注册为 Windows 的服务程序

    将 Tocmat5 0 注册为 Windows 的服务程序 步骤 1 下载 Tomcat 5 0 x 不要下载安装版本 2 解压到 TOMCAT HOME 3 安装或者从别处拷贝JRE 推荐拷贝 可以删除不需要的文件 如文档等 4 在 TO
  • JAVA环境变量的配置及常用工具说明

    首先 到官网www eclipse com下载并安装最新版本的JDK 其次 找到设置位置 我的电脑 右键 属性 高级系统设置 高级 默认 环境变量 系统变量 新建系统变量JAVA HOME和CLASSPATH 变量名 JAVA HOME 变
  • 使用 java 命令编译运行 java 程序

    java 编译的过程 就是将 java 项目从源文件变成 class 文件的过程 而 class 文件 最后会被加载到JVM 中运行 在 JDK bin 目录下 提供了 javac 命令 用于将 java 源文件编译成 class 字节码文
  • 【JDK】Mac版安装JDK并配置环境

    参考文章地址 https www cnblogs com dingzhijie p 7016397 html https blog csdn net deliciousion article details 78046007 教程内容为在M
  • 解决tomcat安装配置后localhost 打不开

    为了这只丑猫能用的方法都用了 终于出来了 也不知道到底哪些是必须的 建议 1 检查端口8080是否被占用 被占用的话参照下方改端口 2 环境变量肯定是要配置的 3 如果以上不可以 那么什么方法都试试吧 前提 下载安装tomcat9和jdk
  • centos7 安装jdk17

    默认情况下 yum 仓库中是没有jdk 17 的 只有jdk 11 所以我们不能直接用yum 安装 需要手动下载进行配置工作 下载文件 wget https download oracle com java 17 latest jdk 17
  • linux的jstack,jmap命令的正确安装附详细教程

    先执行命令 yum list showduplicate su root yum list showduplicate grep i java yum install java 11 openjdk devel x86 64 y jstac
  • Linux - CentOS 6 安装 JDK

    安装步骤如下 1 下载jdk1 7 0 55 jdk 7u55 linux i586 tar gz 2 卸载系统自带的开源JDK 查看是否安装JDK rpm qa grep java 显示如下信息 存在 执行下面代码删除 rpm e jav
  • JDK8升级JDK11最全实践干货来了

    1 前言 截至目前 2023年 Java8发布至今已有9年 2018年9月25日 Oracle发布了Java11 这是Java8之后的首个LTS版本 那么从JDK8到JDK11 到底带来了哪些特性呢 值得我们升级吗 而且升级过程会遇到哪些问
  • 自己动手写CSDN博客提取器,提取文件保存支持PDF、doc、txt三种格式

    转载自 http blog csdn net w397090770 article details 7760907 下载地址http download csdn net detail w397090770 4438566 不需要积分 下面有
  • java中String作为参数传递终极解决

    今天我遇到一个问题就是string的传值问题 它虽然是一个引用数据类型 但是却和基本数据类型一样无法被改变 我看到网上的很多解释都很离谱 比如说很多解释说String要看成和Integer一样的包装类 看成 是char 的包装类 所以和其一

随机推荐

  • 罗马数字转换器(用罗马数字构造元素的值取模实现)

    我的CSDN主页 My Python 学习个人备忘录 我的HOT博 罗马数字转换器 用罗马数字构造单位的值取模实现 刷CSDN无意间看到大佬用C实现的 罗马数字转换器 FreeCodeCamp 不懂C 读不透代码 文中有一句 向下取整 我决
  • 数学建模常用模型和算法介绍

    这里总结了一些数学建模的常用模型和算法 我们给出了相应的模型 算法 描述 相关内容的网页链接 部分模型 算法 给出了全国大学生数学建模竞赛中使用该模型 算法 的优秀论文的例子 模型和算法汇总目录 常见模型 微分方程模型 元胞自动机模型 动态
  • 前端性能优化方案都有哪些?

    前端是庞大的 包括 HTML CSS Javascript Image Flash等等各种各样的资源 前端优化是复杂的 针对方方面面的资源都有不同的方式 那么 前端优化的目的是什么 1 从用户角度而言 优化能够让页面加载得更快 对用户的操作
  • Spring事务的传播行为REQUIRES_NEW和REQUIRED区别

    事务的传播特性指的是当一个事务方法被另一个事务方法调用时 这个事务方法应该如何进行 spring的事务传播行为一共有7种 备注 上面图是从其他博客截取的 忘记链接了 应用场景 A方法中调用B和C方法 其中BC都进行 1操作 括号中的报错意思
  • 华为OD机试真题-光伏场地建设规划【2023Q1】【JAVA、Python、C++】

    题目描述 祖国西北部有一片大片荒地 其中零星的分布着一些湖泊 保护区 矿区 整体上常年光照良好 但是也有一些地区光照不太好 某电力公司希望在这里建设多个光伏电站 生产清洁能源 对每平方公里的土地进行了发电评估 其中不能建设的区域发电量为0k
  • python安装时间过长_python走过的坑(关于python、pip安装)

    第一个坑 python2 or python3 how to choose 变化不大看你目前的研究方向的库支持 python的编辑器选择问题 IDLE Subline text 这属于文本编辑器 pycharm Anaconda IDE集成
  • 【Unity小游戏】游戏开发案例,轻松打造一款塔防游戏!(下)

    欢迎来到如何在 Unity 中创建塔防游戏的第二部分 你正在Unity中制作一个塔防游戏 在第一部分结束时 你可以放置和升级怪物 你还有一个敌人攻击饼干 然而 敌人不知道该面对哪条路 此外 这是攻击的一个严重的失误 在这一部分中 你将添加敌
  • [转载]OpenWRT UCI API的使用

    OpenWRT UCI API的使用 分类 OpenWRT C 2014 03 09 21 51 3551人阅读 评论 4 收藏 举报 目录 原文 http blog csdn net bywayboy article details 20
  • 阿里测试8年,肝到P8只剩他了····

    在阿里工作了8年 工作压力大 节奏快 但是从技术上确实得到了成长 尤其是当你维护与大促相关的系统的时候 熬到P7也费了不少心思 小编也是个爱学习的人 把这几年的工作经验整理成了一份完整的笔记 此笔记已助朋友拿到腾讯 阿里 美团等10个off
  • Python表白代码合集:5种表白代码,找不到对象你来找我,这也太秀了叭

    文章目录 一 容我啰嗦两句 二 来吧 代码展示 1 给女神比个小心心 2 无限弹窗式表白 3 这货不是表白代码 悄悄送给你们 4 520表白墙 5 抖音热门表白小软件 6 无套路表白 三 写在最后 一 容我啰嗦两句 爬虫看多了 对身体不好
  • 在win7中chm打不开的最佳方法

    我今天遇到了个非常棘手的问题 想看看资料 却打不开chm帮助文件 我装的是64位win7 打开chm文件时 系统提示我安全问题 强行打开 却无法显示内容 得到的提示是 该页导航被取消 郁闷啊 头痛啊 怎么办啊 急急如火令 只有找Google
  • uni-app 自定义webview大小

    在uni app中使用web view 组件 默认铺满全屏并且层级高于前端组件 会遮挡页面上的其他组件 在官网中写明 app vue下web view组件不支持自定义样式 默认充满屏幕不可控制大小 nvue web view 必须指定样式宽
  • Unity3D 如何在ECS架构下,用Unity引擎进行游戏开发详解

    前言 Unity3D是一款强大的游戏引擎 它提供了丰富的功能和工具 可以帮助开发者快速构建高质量的游戏 而Entity Component System ECS 是Unity3D中一种新的架构模式 它可以提高游戏的性能和可扩展性 本文将详细
  • go操作excelize报表框架

    Excelize系统设计 养成习惯 再看 源码在文章后面 写在前面 感谢go社区的excelize框架 https github com 360EntSecGroup Skylar excelize 版本说明 这个版本只是第一版 简单利用了
  • 计算0到100中所有含有6的数之和(注意不要生复算66)(用与10取模计算出各位有6的数,用除10 计算十位有6的数)

    import
  • DHCP的概念和原理

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 什么是DHCP 1 dhcp的作用 2 DHCP工作原理 3 DHCP服务器为客户端分配IP地址有三种形式 4 DHCP的好处 5 DHCP种的租期 6 DHC
  • 服务端授权工具可做跟单和程序化交易源码

    源码介绍 MT4行情抓取工具 用vc 开发 源码全开放 速度飞快 功能稳定 界面显示订阅代码的实时数据 直观 操作简单 可以灵活修改 添加订阅代码 订阅需要的行情数据 可用unifeed协议给MT4服务端做数据源 也可以自己修改数据输出格式
  • 58 openEuler搭建Mariadb数据库服务器-管理数据库

    文章目录 58 openEuler搭建Mariadb数据库服务器 管理数据库 58 1 创建数据库 58 2 查看数据库 58 3 选择数据库 58 4 删除数据库 58 5 备份数据库 58 6 恢复数据库 58 openEuler搭建M
  • BLE 蓝牙的一些心得总结

    1 TI 的CC2541协议栈开发教程 https blog csdn net feilusia category 5630377 html 2 以下是我对BLE 蓝牙的一些理解 如果有什么不对的地方 恳请大佬们指点
  • java源码分析-native方法的调用

    java源码分析 native方法的调用 这段时间在分析java源码时 经常能看到很多的底层源码中都调用了被native关键字修饰的方法 也就是java调用本地方法 但是在进行debug时有进不去 看不了具体的实现 因为这写方法是用c c