native关键字的使用
- 一、JVM体系结构
- 二、native是什么?
- 三、native能干什么?
- 四、native怎么使用?
- 五、native总结
在研读**《深入理解Java虚拟机》这本书时,看到 Java 虚拟机运行时数据区中有关本地方法栈**(Native Method Stack)的概念,本地方法栈就是为调用 Native 方法服务的,被 Native 修饰的方法不是由 Java 语言实现的,可以是 C/C++ 实现,然后通过 JNI(Java Native Interface)实现调用。当然也有 Java 虚拟机栈,是为 Java 方法服务的。本篇主要是 Native 关键字的介绍。
一、JVM体系结构
本文主要介绍 JVM 体系结构中的一小块区域,即:
二、native是什么?
native 是一个计算机函数,一个 Native Method 就是一个 Java 调用 非Java 代码的接口。方法的实现由 非Java 语言实现,比如 C 或 C++。
一个 Native Method 是这样一个 Java 的方法:该方法的实现由 非Java 语言实现,比如 C。这个特征并非 Java 语言 所特有,很多其它的编程语言都有这一机制,比如在 C++ 中,你可以用 extern “C” 告知 C++ 编译器去调用一个 C 的函数。
native 是与 C++ 联合开发的时候用的!使用 native 关键字说明这个方法是原生函数,也就是这个方法是用 C/C++ 语言实现的,并且被编译成了 DLL ,由 Java 去调用。 这些函数的实现体在 DLL 中,JDK 的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是 Java 的底层机制。
三、native能干什么?
native 是修饰方法使用的。用 native 修饰的方法表明这个方法是一个调用非 Java 代码的接口。方法的实现由 非Java 语言实现,比如 C 或者 C++,当然也可以是其他语言。
四、native怎么使用?
先看一下 Java 源码中如何使用的。以下是开启一个线程,启动时的源码:(在Thread类中)
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the start method) and the * other thread (which executes its run method).
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already
* started.
* @see #run()
* @see #stop()
*/
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
请注意上述代码中的最后一行,这里是一个特殊的方法,我们基本没有写过,如果不读源码也不会看见有这样的写法。
private native void start0();
我们可以看到 start() 方法里调用了一个 start0(); 方法,接着往下找到 start0() 方法,而 start0() 方法则是此类中一个私有的方法,也没有方法体。感觉奇怪吗?但是它就是这样的写法。
从源码中我们就可以知道它是如何使用的了,即在类中写一个使用 native 关键字修饰的方法,并且此方法没有方法体。这就是 native 关键字的使用方法。
此方法写完之后就不用管它了,剩下的交给 JVM 处理。
package com.iot.back.streamserver.controller;
/**
* <p>NativeTest 此类用于:</p>
* <p>@author:hujm</p>
* <p>@date:2022年11月26日 20:42</p>
* <p>@remark:</p>
*/
public class NativeTest {
public static void main(String[] args) {
new Thread(() -> {
System.out.println("This is my thread!");
}, "My Thread").start();
NativeTest nativeTest = new NativeTest();
// 调用我们自己写的本地方法,这就完成了使用。非常简单
nativeTest.helloWorld();
}
/**
* 这里就是我们写的被 native 关键字修饰的 HelloWorld 的本地方法。
*/
private native void helloWorld();
}
native 的使用方法就是这么简单。
我们只需要记:凡是带了 native 关键字的,说明此方法已经超出了 Java 的作用范围了,表明该方法调用了底层 C/C++ 语言的库了。此类方法会进入本地方法栈,调用本地方法本地接口(JNI),关于 JNI 的介绍有很多,放在另一篇博客中。在这里只需要知道 JNI 的作用即可。
JNI 的作用:扩展了 Java 的使用,融合了不同的编程语言为 Java 所用!最初是想调用 C/C++ 语言。
至于 native 方法如何调用 非 Java 语言的接口的方式和示例我们在另外一篇博客中再详细展开。
五、native总结
- native 是一个关键字,其修饰的方法只说明,不实现;
- native 方法会被加载到本地方法栈中;
- native 并不是 Java 语言实现的,所以在使用此类方法时直接调用即可,不需要管它的底层实现;
- native 方法是 Java 语言调用其他语言的时候使用的,底层实现不是 Java;
- native 方法实际上是 Java 语言调用底层操作系统的方法,Java 只能调用,不能查看和修改;
- Java 语言是跨平台的,自然而然会失去对底层的控制,所以想要调用底层方法,就必须使用 native 方法间接调用底层操作系统的方法;
- native 方法在企业级应用中较为少见,随着 Java 语言的发展,native 方法越来越少;
关于 native 的介绍,仅是个人见解,如果有错误之处,欢迎在评论区指教!
完结!