Java中的本机方法是什么?应该在哪里使用它们?

Java中的本机方法是什么?应该在哪里使用它们?,java,native,Java,Native,本机方法与抽象方法具有相同的语法,但它在哪里实现 我想知道我们在哪里使用本地方法 理想情况下,一点也不。实际上,有些功能在Java中是不可用的,您必须调用一些C代码 这些方法是用C代码实现的。该方法是用“本机”代码实现的。也就是说,不在JVM中运行的代码。它通常用C或C++编写。 本地方法通常用于与系统调用或其他编程语言编写的库进行接口。本机方法允许您在java代码中使用其他语言(如C或C++)的代码。当java不能提供您需要的功能时,您可以使用它们。例如,如果我正在编写一个程序来计算某个方程并

本机方法与抽象方法具有相同的语法,但它在哪里实现

我想知道我们在哪里使用本地方法

理想情况下,一点也不。实际上,有些功能在Java中是不可用的,您必须调用一些C代码


这些方法是用C代码实现的。

该方法是用“本机”代码实现的。也就是说,不在JVM中运行的代码。它通常用C或C++编写。

本地方法通常用于与系统调用或其他编程语言编写的库进行接口。

本机方法允许您在java代码中使用其他语言(如C或C++)的代码。当java不能提供您需要的功能时,您可以使用它们。例如,如果我正在编写一个程序来计算某个方程并创建它的折线图,我会使用java,因为它是我最擅长的语言。然而,我也精通C语言。比如说,在我的程序中,我需要计算一个非常复杂的方程。我会使用一个本地方法,因为我知道一些C++,我知道C++比java快很多,所以如果我用C++编写了我的方法,它会更快。另外,假设我想与另一个程序或设备交互。这也会使用一个本地方法,因为C++有一个叫做指针的东西,它允许我这样做。

< p> java本机代码必需品:

  • h/w访问和控制
  • 使用商业软件和系统服务[硬件相关]
  • 使用尚未或无法移植到Java的遗留软件
  • 使用本机代码执行时间关键型任务
希望以下几点能回答您的问题:)

Java中的本机方法是什么?应该在哪里使用它们

一旦你看到一个小例子,你就会明白:

Main.java

public class Main {
    public native int intMethod(int i);
    public static void main(String[] args) {
        System.loadLibrary("Main");
        System.out.println(new Main().intMethod(2));
    }
}
#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_intMethod(
    JNIEnv *env, jobject obj, jint i) {
  return i * i;
}
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
  -I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
4
Main.c

public class Main {
    public native int intMethod(int i);
    public static void main(String[] args) {
        System.loadLibrary("Main");
        System.out.println(new Main().intMethod(2));
    }
}
#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_intMethod(
    JNIEnv *env, jobject obj, jint i) {
  return i * i;
}
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
  -I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
4
输出

public class Main {
    public native int intMethod(int i);
    public static void main(String[] args) {
        System.loadLibrary("Main");
        System.out.println(new Main().intMethod(2));
    }
}
#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_intMethod(
    JNIEnv *env, jobject obj, jint i) {
  return i * i;
}
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
  -I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
4
在带有Oracle JDK 1.8.0_45的Ubuntu 14.04上测试

因此,很明显,它允许您:

  • 使用Java中的任意汇编代码调用编译的动态加载库(此处用C编写)
  • 并将结果返回到Java中
这可用于:

  • 使用更好的CPU汇编指令在关键部分编写更快的代码(不是CPU可移植的)
  • 直接进行系统调用(非操作系统便携式)
在可移植性较低的情况下进行权衡

您也可以从C调用Java,但必须首先在C中创建JVM:


给你玩

你的意思是,如果我的类中有一个原生方法forName,那么它的实现就是系统调用的一部分。要使用的本机方法是否与系统调用的名称不完全相同。如果在一个名为“com.example.Foo”的类中有一个名为“forName”的方法,那么将被调用的C函数的名称将类似于“Java\u com\u example\u Foo\u forName”。然后,该函数可以依次调用系统调用。有关更多详细信息,请参阅。如果本机方法是用其他名称实现的,如C中的Java_com_example_Foo_forName,那么我们如何知道我们给出的本机方法的名称(forName)是正确使用的呢。我的意思是Java_com_example_Foo_forName有着完全不同的名称,它看起来像是C语言中的一个本地方法,人们在理解它是自己方法的实现而不是同名的实现时会感到困惑。你所解释的我明白了,但我无法理解实现是如何进行的。一般来说,你不能不看文档和/或源代码就知道本机方法将调用什么,就像任何其他方法一样。仅仅因为它被称为“forName”,并不意味着它将调用该名称的系统调用,但人们希望作者使用合理的命名约定。顺便说一句,当我说它们用于与系统调用接口时,我并不是说它们与系统调用是一对一的。与系统调用接口只是本机方法的一种常见用法。假设我们想调用一些系统函数,
baz
。首先,使用本机方法
bar
创建一个名为
com.example.Foo
的类。然后编写一个C函数,
Java\u com\u example\u Foo\u bar
,它调用
baz
。编译C函数并将其链接到共享库中(例如:
libqux.so
qux.dll
)。Java代码必须在调用
bar
本机方法之前调用
System.loadLibrary(“quux”)
(或者将抛出
未满足的链接错误
)。在本例中,只要允许,我都会使用不同的名称,但实际上类和库的名称会相似,函数和方法的名称也会相似。@CiroSantilli六四事件法轮功 是的,谢谢。为你的幽默感(第一行)投票吧。它工作得很好……你做得很好,兄弟。。。我已经尝试了很多教程,但没有得到一个有效的答案example@dom谢谢我猜这是因为它是高度依赖于系统的东西。这就是为什么我总是说在:-)@Ciro上测试的发行版版本:什么是JNIEXPORT jint JNICALL。它是用于本机应用程序的语法。@niks stuff在
jni.h
中定义。看起来是推荐的/最便携的方法。不知道在哪里有文档记录,希望有链接。I/O呢?或者这属于“使用未移植到Java或无法移植到Java的遗留软件”。我想知道,因为FileNotFoundException类有本机I/O方法。@RnBandCrunk:是的,你是对的。I/O通常依赖于系统,必须使用本机方法来实现这些操作。