JNI的用处

9

我已经成为一名Java开发者几年了,听说JNI可以做一些非常有用和强大的事情。我不知道是因为我没有需要使用它还是它对我来说不是非常相关;但我从未接触过它。

我想知道Java这个方面的用处是什么。最好能给出一些例子。


现在的Java(-server版本)在大多数实际用例中与C++的速度差别不大,调用特殊系统API也是相当特定的情况。最常见的使用情况是当您需要使用一些库(数学或其他特定库),这些库很久以前就是用C/C++编写的,并且仍然得到支持,但没有Java版本的这个库。 - Zorkus
5个回答

14

这非常有用。我可以看到使用JNI的两个主要原因(可能还有更多)。

  1. 性能。如果您有一段代码,由于某种原因Java运行时无法满足性能要求,则可以在本地代码中实现该函数并从Java中调用它。如果您真的需要的话,可以手动调整实现。然而这很可能是最不常见的原因,因为Java通常表现良好。

  2. 访问操作系统特定的APIs。这个原因非常重要。我曾经遇到一个需要在Java中做一些事情但也需要访问Java无法提供的东西的情况。在我的情况下,这是UNIX域套接字。由于它们是UNIX特定的,没有标准的Java方式来使用它们。所以我创建了一个类,在C中包装套接字并使用JNI进行访问。问题解决了。


嘿...你的第二个答案让我想起了大学时我的汇编课程——我们必须结合汇编和C函数来完成一个作业。真是很有趣的东西。 - javamonkey79
你可以将第二点推广到所有外部 C/C++ 库,这些库是你的 Java 软件必须依赖的。 - Guillaume

4

我为iSeries编写了一个广泛的JNI层,以便访问DB2、用户队列、数据队列和其他一些OS/400特定功能。如果没有JNI,我们在iSeries上的大部分系统将无法实现。因此,是的,JNI有它的位置,当你需要它时,你确实需要它。

相对于纯Java来说,它相对困难,但功能强大且不可怕。

此外,每当我查看一些JNI代码时,我也会考虑使用JNA


我不认为我以前见过JNA,哇,我太菜了!嘿,谢谢:D - javamonkey79
不客气;我从来没有使用过它,因为我对本地支持的需求是(iSeries),而且已经在几年前完成和稳定了...但我对它很感兴趣,如果我需要Windows或Linux的本地访问,我会尝试它。 - Lawrence Dol

2
我能想到以下几种用途:
  1. 与现有低级别(C/C++) API 集成,这些API没有Java对应项
  2. 与系统的某些方面集成,这些方面不能通过可用的Java API(例如直接硬件访问等)暴露出来
有人可能会说,使用JNI可以创建高度优化的代码部分,但是随着现代JVM的发展,您已经得到了相当快速的性能,而使用JNI所带来的复杂性可能会超过您可能看到的任何性能好处。

我同意,但实际上,你的理由1和2其实是同一件事情,因为任何像直接硬件访问这样的东西都可以通过C/C++ API来实现。你不能用Java编写驱动程序,所以你必须像C一样访问它 :-P。 - Evan Teran
对于#1,我更多地考虑第三方(或遗留)API,它们没有Java实现甚至源代码(只有一个链接到的库)。对于#2,我更多考虑你的#2,即符号链接支持。 - Marc Novakowski

1

绑定FFMPeg进行C解码(几乎任何)视频/音频格式有一些用途。

还有JNA,它使您感觉像在使用库本身。从这个角度来看,“更容易”,因为它将所有内容传递给Java开发人员进行管理,但从另一个角度来看,您必须弄清楚结构映射并做大量繁重的工作才能正确传递所有指针等。


我使用JNI将Swing应用程序绑定在一起,以便以可移植的方式解码MPEG(考虑Linux、x64、Windows、OS X)。这是一团糟,但最终还是成功了。 - Miguel Ping
同样也有FFmpeg的JNI绑定。我使用JNA,因为我需要访问那些绑定没有通过JNI层传递的结构体。 - Rob Elsner

1

我们有一个需求,需要在运行在Suse Linux上的遗留C应用程序周围包装一个新的UI。JNI是完成这项工作的完美工具。

总的来说,我认为JNI与Java的“编写一次,随处运行”的概念相矛盾。然而,在某些情况下,JNI可以很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接