当前位置: 首页 > news >正文

【JVM】本地方法接口 Native Interface

图片

一、JNI简介

JVM本地方法接口(Java Native Interface,JNI)是一种允许Java代码调用本地方法(如C或C++编写的方法)的机制。这种技术通常用于实现高性能的计算密集型任务,或者与底层系统库进行交互。

二、JNI组成

  • Java类中的native方法:在Java类中使用native关键字声明一个本地方法,表示该方法将由本地代码实现。

  • JNI头文件:使用Java Native Interface工具(javac、javah)生成本地方法的头文件,该头文件中包含了本地方法的声明和参数列表等信息。

  • 本地代码实现:根据生成的头文件,在本地代码中实现对应的本地方法。可以使用C、C++等语言编写本地代码,并通过编译器将其编译成动态链接库(DLL)或共享库(SO)。

三、JNI的作用

  1. 提高性能:通过将计算密集型任务交给本地代码实现,可以提高程序的性能。因为本地代码可以直接操作内存和硬件资源,而不需要经过Java虚拟机的额外开销。

  2. 与底层系统库交互:JNI可以方便地与底层系统库进行交互,例如访问操作系统、数据库、网络等资源。

  3. 扩展Java功能:通过JNI,可以将其他编程语言的功能集成到Java程序中,从而扩展Java的功能。

四、本地方法

简单来讲,一个Native Method就是一个Java调用非Java代码的接口。一个Native Method是这样一个java方法:该方法的实现由非Java语言实现,比如C。这个特征并非Java特有,很多其他的编程语言都有这一机制,比如在C++ 中,你可以用extern “C” 告知C++ 编译器去调用一个C的函数。

在定义一个native method时,并不提供实现体(有些像定义一个Java interface),因为其实现体是由非java语言在外面实现的。

本地接口的作用是融合不同的编程语言为Java所用,它的初衷是融合C/C++程序。

标识符native可以与所有其它的java标识符连用,但是abstract除外。这是合理的,因为native暗示这些方法是有实现体的,只不过这些实现体是非java的,但是abstract却显然的指明这些方法无实现体。native与其它java标识符连用时,其意义同非Native Method并无差别,比如native static表明这个方法可以在不产生类的实例时直接调用,这非常方便,比如当你想用一个native method去调用一个C的类库时。上面的第三个方法用到了native synchronized,JVM在进入这个方法的实现体之前会执行同步锁机制(就像java的多线程。)

一个native method方法可以返回任何java类型,包括非基本类型,而且同样可以进行异常控制。这些方法的实现体可以制一个异常并且将其抛出,这一点与java的方法非常相似。当一个native method接收到一些非基本类型时如Object或一个整型数组时,这个方法可以访问这非些基本型的内部,但是这将使这个native方法依赖于你所访问的java类的实现。有一点要牢牢记住:我们可以在一个native method的本地实现中访问所有的java特性,但是这要依赖于你所访问的java特性的实现,而且这样做远远不如在java语言中使用那些特性方便和容易。

native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法。JVM将控制调用本地方法的所有细节。需要注意当我们将一个本地方法声明为final的情况。用java实现的方法体在被编译时可能会因为内联而产生效率上的提升。但是一个native final方法是否也能获得这样的好处却是值得怀疑的,但是这只是一个代码优化方面的问题,对功能实现没有影响。

如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用java语言重写这个方法(这个似乎看起来有些奇怪),同样的如果一个本地方法被fianl标识,它被继承后不能被重写。

本地方法非常有用,因为它有效地扩充了jvm.事实上,我们所写的java代码已经用到了本地方法,在sun的java的并发(多线程)的机制实现中,许多与操作系统的接触点都用到了本地方法,这使得java程序能够超越java运行时的界限。有了本地方法,java程序可以做任何应用层次的任务。

图片

五、使用native method

1. 与Java环境外交换

需要和Java外面的环境进行交互,这是本地方法存在的主要原因。比如和操作系统或者某些硬件交换信息时,本地方法就为我们提供了方便简洁的接口。

2. 与操作系统交互

通过使用本地方法,Java实现了JRE与底层系统的交互,甚至JVM的一部分就是使用 C 写的。另外如果我们要使用Java未提供的封装的操作系统的特性时,也需要使用到本地方法。就像Java创建的线程最终还是要回归到操作系统的本地线程。

3. Sun’s Java

Sun的解释器是用 C 实现的,使得它能像一些普通的 C 一样与外部交互。例如类 java.lang.Thread 的 setPriority() 方法是通过java 实现的,但是它实际调用的是该类里的本地方法 setPriority0()。

六、JNI源码解读

JNI源码解读主要包括以下几个部分:

  • JNI头文件:包含JNI函数声明和结构体定义。例如,jintArray、jbooleanArray等类型的声明。

  • JNI函数实现:这些函数是在C或C++中实现的,它们提供了与JNI头文件中声明的函数对应的本地方法。例如,GetStringUTFChars、ReleaseStringUTFChars等函数。

  • JNI函数指针:这些指针指向JNI函数实现。在Java代码中,可以使用这些指针来调用本地方法。

  • Java类和方法:这些类和方法用于在Java代码中声明本地方法。例如,public native void nativeMethod();表示一个本地方法。

  • 加载和链接本地库:在Java程序启动时,需要加载包含本地方法实现的本地库。然后,JVM会将这些本地方法与Java类和方法关联起来。

以下是一个简单的JNI源码示例:


#include <jni.h>
#include "HelloJNI.h"
#include <stdio.h>JNIEXPORT jstring JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject obj) {return (*env)->NewStringUTF(env, "Hello from C!");
}

在这个示例中,我们实现了一个名为sayHello的本地方法,它返回一个字符串"Hello from C!"。要使用这个本地方法,需要在Java代码中声明它:


public class HelloJNI {static {System.loadLibrary("hello-jni");}public native String sayHello();public static void main(String[] args) {HelloJNI hello = new HelloJNI();String result = hello.sayHello();System.out.println(result);}
}

编译并运行这个Java程序,将看到输出"Hello from C!"。

七、结语

目前该方法的使用越来越少了,除非是与硬件有关的应用,比如通过java程序驱动打印机或者java系统管理生产设备,在企业级应用已经比较少见。因为现在的异构领域间的通信很发达,比如可以使用Socket通信,也可以是用Web Service等等。

需要注意的是,由于本地方法可能会破坏Java的安全性和可移植性,因此在使用JNI时需要谨慎操作。此外,虚拟机保证在同一Java线程中多次调用同一本地方法时,传递给该本地方法的JNI接口指针是相同的。

图片

相关文章:

【JVM】本地方法接口 Native Interface

一、JNI简介 JVM本地方法接口&#xff08;Java Native Interface&#xff0c;JNI&#xff09;是一种允许Java代码调用本地方法&#xff08;如C或C编写的方法&#xff09;的机制。这种技术通常用于实现高性能的计算密集型任务&#xff0c;或者与底层系统库进行交互。 二、JNI组…...

JS 本地存储 sessionStorage localStorage

本地存储 随着互联网的快速发展&#xff0c;基于网页的应用越来越普遍&#xff0c;同时也变的越来越复杂&#xff0c;为了满足各种各样的需求&#xff0c;会经常性在本地存储大量的数据&#xff0c;HTML5规范提出了相关解决方案。 本地存储特性 1、数据存储在用户浏览器中 2…...

K8S 存储卷

意义&#xff1a;存储卷----数据卷 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的&#xff0c;delete,k8s用控制器创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会回复到初始状态 一旦回到初始状态&#xff0c;所有的后天编辑的文件…...

一个SqlSugar实际案例

SqlGugar是一个非常好的数据库操作框架&#xff0c;今天用一个示例来分享如何使用。 新建一张课程表 结构如下&#xff1a; CREATE TABLE t_course (id int NOT NULL AUTO_INCREMENT COMMENT ID,title varchar(1024) NOT NULL COMMENT 课程标题,description text NOT NULL C…...

【RT-DETR有效改进】ShapeIoU、InnerShapeIoU关注边界框本身的IoU(包含二次创新)

前言 大家好&#xff0c;我是Snu77&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本&#xff0c;同时修改内容也支持Re…...

从理论到实践:数字孪生技术的全面应用探讨

数字孪生是一种将实际物体或系统的数字模型与其实时运行状态相结合的概念。这一概念的核心在于创建一个虚拟的、与真实世界相对应的数字副本&#xff0c;以便监测、分析和优化实体系统的性能。 简单理解&#xff0c;数字孪生就是在一个设备或系统的基础上&#xff0c;创造一个…...

2.1.2 一个关于y=ax+b的故事

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1、投资&技术   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas   1.2 金融数据处理   1.3 金融数据可视化 2、投资方法论   2.1.1 预期年化收益率   2.1.2 一个关于yaxb的…...

Rust-解引用

“解引用”(Deref)是“取引用”(Ref)的反操作。取引用&#xff0c;我们有&、&mut等操作符&#xff0c;对应的&#xff0c;解引用&#xff0c;我们有操作符&#xff0c;跟C语言是一样的。示例如下&#xff1a; 比如说&#xff0c;我们有引用类型p:&i32;,那么可以用符…...

记录一下vue项目引入百度地图

公共部分 #allmap { width: 500px; height: 500px; font-family: "微软雅黑"; } 1、 <div id"allmap"> <baidu-map :center"center" :zoom"zoom" ready"handler"></baidu-map> </div> data()…...

基于Docker官方php:7.4.33-fpm镜像构建支持67个常见模组的php7.4.33镜像

实践说明&#xff1a;基于RHEL7(CentOS7.9)部署docker环境(23.0.1、24.0.2)&#xff0c;所构建的php7.4.33镜像应用于RHEL7-9(如AlmaLinux9.1)&#xff0c;但因为docker的特性&#xff0c;适用场景是不限于此的。 文档形成时期&#xff1a;2017-2023年 因系统或软件版本不同&am…...

opencv通过轮廓点生成闭合图像

前言 有时候需要将某一些点生成闭合的二值图像。记录一下。 // 轮廓点个数 int nrCurvePoints curContour.nr; // 轮廓点 DIM2DL* curvePoints curContour.pts;std::vector<cv::Point> points; // 轮廓点集合 for (int cntPoint 0; cntPoint < nrCurvePoints; cn…...

Python 网络编程之TCP详细讲解

【一】传输层 【1】概念 传输层是OSI五层模型中的第四层&#xff0c;负责在网络中的两个端系统之间提供数据传输服务主要协议包括**TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;** 【2】功能 **端到端通信&#xff1a;**传输层负责…...

直饮水系统服务认证:提升水质与安全的必要举

直饮水系统作为一种便捷、卫生的饮水方式&#xff0c;已经越来越受到人们的欢迎。然而&#xff0c;随着市场的发展&#xff0c;直饮水系统的质量和服务也面临着一些挑战。因此&#xff0c;直饮水系统服务认证应运而生&#xff0c;成为了提升水质与安全的必要举措。 一、直饮水…...

Qt 调试系统输出报警声以及添加资源

文章目录 前言一、方法1 使用 Qsound1.添加都文件 直接报错2.解决这个错误 添加 QT multimedia3. 加入代码又遇到新的错误小结 二、第二种方法1.引入库2.添加资源2.1依次点击Qt--->Qt Resource File--->Choose2.2给资源文件起个名字&#xff0c;如&#xff1a;res&#…...

Linux下文件的创建写入读取编程

在linux下操作一个文件&#xff0c;首先要保证文件的存在&#xff08;不存在就创建&#xff09;&#xff0c;接着打开文件&#xff08;打开成功&#xff09;并得到文件描述符&#xff0c;接着在进行读写操作&#xff0c;最后还需要关闭文件。如果我们对文件进行读写之后不关闭文…...

python 解析

list(pd.DataFrame) # 所有列名切片&#xff1a;print("显式 切片:\n", df.loc[:, "number":"sum"]) 所有行&#xff0c;列是从number 到sum &#xff0c;前闭后开print("隐式 切片:\n", df.iloc[:, 1:3]) # 结果和上面一样转化成字典…...

谷歌aab包在Android 14闪退而apk没问题(targetsdk 34)

问题原因 Unity应用(target SDK 34)上线到GooglePlay&#xff0c;有用户反馈fold5设备上&#xff08;Android14系统&#xff09;疯狂闪退&#xff0c;经测试&#xff0c;在小米手机Android14系统的版本复现成功了&#xff0c;奇怪的是apk直接安装没问题&#xff0c;而打包成aa…...

34.在排序数组中查找元素的第一个和最后一个位置

34.在排序数组中查找元素的第一个和最后一个位置 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为…...

js树过滤

// 递归过滤得到每一项的hidden为false的数据 function filterTree(arr) { return arr.filter(item > { if (item.children) { item.children filterTree(item.children) } if (!item.hidden) { return true } }) }...

Java多线程并发篇----第十六篇

系列文章目录 文章目录 系列文章目录前言一、线程等待(wait)二、线程睡眠(sleep)三、线程让步(yield)四、线程中断(interrupt)五、Join 等待其他线程终止前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这…...

推进军民融合标准化建设,超导磁探测军民应用前景广阔

作为首都科技创新与产业融合核心&#xff0c;北京市正以标准化为抓手&#xff0c;推进军民融合深度发展&#xff0c;重点落实军民融合标准化试点任务&#xff0c;探索建设军民通用标准信息化平台&#xff0c;打通“军标—民标”转化堵点。依托首都科研、企业集聚优势&#xff0…...

LocalVocal:本地化语音识别的隐私保护方案 - 从部署到优化的全流程指南

LocalVocal&#xff1a;本地化语音识别的隐私保护方案 - 从部署到优化的全流程指南 【免费下载链接】obs-localvocal OBS plugin for local speech recognition and captioning using AI 项目地址: https://gitcode.com/gh_mirrors/ob/obs-localvocal 在数字化沟通日益频…...

3分钟免费搞定Axure RP中文汉化:完整语言包安装指南

3分钟免费搞定Axure RP中文汉化&#xff1a;完整语言包安装指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的…...

nfs-subdir-external-provisioner核心配置参数详解:onDelete、archiveOnDelete、pathPattern

nfs-subdir-external-provisioner核心配置参数详解&#xff1a;onDelete、archiveOnDelete、pathPattern 【免费下载链接】nfs-subdir-external-provisioner Dynamic sub-dir volume provisioner on a remote NFS server. 项目地址: https://gitcode.com/gh_mirrors/nf/nfs-s…...

Pumba在Kubernetes中的实战部署:DaemonSet配置指南

Pumba在Kubernetes中的实战部署&#xff1a;DaemonSet配置指南 【免费下载链接】pumba Chaos testing, network emulation, and stress testing tool for containers 项目地址: https://gitcode.com/gh_mirrors/pu/pumba Pumba是一款强大的容器混沌测试工具&#xff0c;…...

Chrome for Testing 问题解决方案:测试环境搭建与兼容性保障(3个实战案例)

Chrome for Testing 问题解决方案&#xff1a;测试环境搭建与兼容性保障&#xff08;3个实战案例&#xff09; 【免费下载链接】chrome-for-testing 项目地址: https://gitcode.com/gh_mirrors/ch/chrome-for-testing Chrome for Testing 是一个专为浏览器自动化测试打…...

美胸-年美-造相Z-Turbo创意工坊:支持批量生成、种子固定、参数网格搜索功能

美胸-年美-造相Z-Turbo创意工坊&#xff1a;支持批量生成、种子固定、参数网格搜索功能 如果你正在寻找一个能稳定、高效生成特定风格图片的AI工具&#xff0c;特别是对“美胸-年美”这类风格有需求&#xff0c;那么你找对地方了。今天要介绍的这个工具&#xff0c;不仅部署简…...

lychee-rerank-mm环境部署:NVIDIA驱动470+、CUDA 12.x兼容性验证清单

lychee-rerank-mm环境部署&#xff1a;NVIDIA驱动470、CUDA 12.x兼容性验证清单 1. 项目概述与核心价值 lychee-rerank-mm是一个专为RTX 4090显卡优化的多模态重排序系统&#xff0c;基于Qwen2.5-VL架构和Lychee-rerank-mm模型构建。这个系统能够对批量图片与文本描述进行智能…...

AI辅助游戏开发新体验:让快马平台的AI模型为你的Superpowers项目编写剧情与平衡技能

最近在尝试用Superpowers框架开发一款魔法题材的RPG游戏&#xff0c;发现InsCode(快马)平台的AI辅助功能特别适合快速原型开发。这里分享下如何用AI模型辅助完成游戏剧情脚本和技能平衡设计的实践过程。 剧情脚本生成 输入"魔法学校学徒发现古老卷轴"这个简单设定后&…...

Citra模拟器终极指南:免费畅玩3DS游戏的完整教程

Citra模拟器终极指南&#xff1a;免费畅玩3DS游戏的完整教程 【免费下载链接】citra A Nintendo 3DS Emulator 项目地址: https://gitcode.com/gh_mirrors/cit/citra 任天堂3DS模拟器Citra是一款开源的高性能游戏模拟工具&#xff0c;让PC用户能够流畅体验《精灵宝可梦》…...