写点什么

我看 JAVA 之 Object & JNI

用户头像
awen
关注
发布于: 2021 年 02 月 26 日

我看 JAVA 之 Object & JNI

注:基于 jdk11

Object

Object 类是 java 语言中所有类的父类。


public class Object { //注册本地函数,方可以从库中的本机代码调用JNI函数 private static native void registerNatives(); static { registerNatives(); }
/** * Constructs a new object. */ //HotSpotIntrinsicCandidate注解,说明本方法,jvm额外维护了一个利用了CPU指令的高效实现 @HotSpotIntrinsicCandidate public Object() {}
//返回对象的运行时类型 /** * Number c = 0; * Class<? extends Number> clazz = c.getClass(); * System.out.println(clazz); * 打印如下: * class java.lang.Integer * 关于泛型及泛型擦除概念,见后续泛型章节 */ @HotSpotIntrinsicCandidate public final native Class<?> getClass();
/** * 返回对象的hash码,hashCode方法支持hash表(比如java.util.HashMap)的特性, * 不同的对象返回唯一的has码,可以提高hash表数据结构的性能。 * hashCode有时候以对象内存地址的机制生成,有时候不是 * java.lang.System.identityHashCode 工具方法 返回默认hashCode()方法的值,null引用返回的hash码为0 */ @HotSpotIntrinsicCandidate public native int hashCode();
/** * 标示其他对象与当前对象是否相等 * 自反性: 自己(非null)与自己比较永远相当 * 对称性: x vs y or y vs x 等价 * 可传递: x.equals(y) == true and y.equals(z), then x.equals(z) * 一致性: 一旦x.equals(y) == true, then anytime x.equals(y) == true * any not null value not equals null * 如果覆盖equals方法,一定要覆盖hashCode方法 */ public boolean equals(Object obj) { return (this == obj); }
/** * clone返回会返回一个相同类型的新对象拷贝,如果要实现克隆,那么当前类及其父类需要实现cloneable接口。 * 对于复杂类型,默认的clone方式仅实现”浅克隆”,如果要实现”深克隆”,需要覆盖clone方法。 * 注:在软件编程中,推荐使用工具类的方式做copy,而不是覆盖clone的方式 */ @HotSpotIntrinsicCandidate protected native Object clone() throws CloneNotSupportedException;
/** * 默认返回 getClass().getName() + '@' + Integer.toHexString(hashCode()) * 具体类可以覆盖Object的toString()方法 */ public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
/** * 持有该对象锁的线程通过调用notify唤醒等待此对象监视器的某一个线程,选择是随机的(具体由不同虚拟机实现)。一次只能有一个线程持有对象锁。 * 获取对象锁定三种方式如下:
 * 1,通过执行该对象的同步实例方法 * 2,通过执行该对象的同步代码块 * 3,通过执行类的同步静态方法 * 见 /openjdk/hotspot/src/share/vm/prims/jvm.cpp line: 526~530 * 见 /openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp line: 407~411 * @throws IllegalMonitorStateException if the current thread is not * the owner of this object's monitor. * @see java.lang.Object#notifyAll() * @see java.lang.Object#wait() */ @HotSpotIntrinsicCandidate public final native void notify();
/** * 持有该对象锁的线程通过调用notify唤醒等待此对象监视器的所有线程。当当前线程释放对象监视器后,其他唤醒的线程会竞争对象监视器。 * * @throws IllegalMonitorStateException if the current thread is not * the owner of this object's monitor. * @see java.lang.Object#notify() * @see java.lang.Object#wait() */ @HotSpotIntrinsicCandidate public final native void notifyAll();
/** * 调用此方法会导致当前对象进入等待状态,知道被其他线程唤醒(notify)或中断(InterruptedException)。相当于wait(0L) * * @throws IllegalMonitorStateException if the current thread is not * the owner of the object's monitor * @throws InterruptedException if any thread interrupted the current thread before or * while the current thread was waiting. The <em>interrupted status</em> of the * current thread is cleared when this exception is thrown. * @see #notify() * @see #notifyAll() * @see #wait(long) * @see #wait(long, int) */ public final void wait() throws InterruptedException { wait(0L); }
/** * * @param timeoutMillis the maximum time to wait, in milliseconds * @throws IllegalArgumentException if {@code timeoutMillis} is negative * @throws IllegalMonitorStateException if the current thread is not * the owner of the object's monitor * @throws InterruptedException if any thread interrupted the current thread before or * while the current thread was waiting. The <em>interrupted status</em> of the * current thread is cleared when this exception is thrown. * @see #notify() * @see #notifyAll() * @see #wait() * @see #wait(long, int) */ public final native void wait(long timeoutMillis) throws InterruptedException;
/** * 在并发编程章节重点讲解 * @param timeoutMillis the maximum time to wait, in milliseconds * @param nanos additional time, in nanoseconds, in the range range 0-999999 inclusive * @throws IllegalArgumentException if {@code timeoutMillis} is negative, * or if the value of {@code nanos} is out of range * @throws IllegalMonitorStateException if the current thread is not * the owner of the object's monitor * @throws InterruptedException if any thread interrupted the current thread before or * while the current thread was waiting. The <em>interrupted status</em> of the * current thread is cleared when this exception is thrown. * @see #notify() * @see #notifyAll() * @see #wait() * @see #wait(long) */ public final void wait(long timeoutMillis, int nanos) throws InterruptedException { if (timeoutMillis < 0) { throw new IllegalArgumentException("timeoutMillis value is negative"); }
if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); }
if (nanos > 0) { timeoutMillis++; }
wait(timeoutMillis); }
/** * 通知垃圾回收器当前对应已经没有引用了,具体回收还要看jvm内部实现。 * jdk9 标记为已过时,在jvm原理章节重点讲解 * * @throws Throwable the {@code Exception} raised by this method * @see java.lang.ref.WeakReference * @see java.lang.ref.PhantomReference * @jls 12.6 Finalization of Class Instances */ @Deprecated(since="9") protected void finalize() throws Throwable { }}
复制代码


JNI(Java Native Interface)

java 本地接口,意为 JAVA 语言提供一套规范供操作系统底层实现,一般是 C/C++语言,不同操作系统版本的 jvm 提供了相应的实现,以达到"Write Once Run Anywhere“

----

实现 JNI 大致步骤如下


  1. 定义 java 程序

```java

package chapter01;


public class TestJNI {


public native void hello();//所有 native 关键词修饰的都是对本地的声明

static {

System.loadLibrary("hello");//载入本地库

}

public static void main(String[] args) {

new TestJNI().hello();

}

}

```

  1. 编译 javac chapter01/TestJNI.java,生成 TestJNI.class

  2. 执行 javac chapter01/TestJNI.java -h . ,生成 JAVA 本地接口 chapter01_TestJNI.h

```c

/ DO NOT EDIT THIS FILE - it is machine generated /

#include <jni.h>

/ Header for class chapter01_TestJNI /


#ifndef Includedchapter01_TestJNI

#define Includedchapter01_TestJNI

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: chapter01_TestJNI

* Method: hello

* Signature: ()V

*/

JNIEXPORT void JNICALL Javachapter01TestJNI_hello

(JNIEnv *, jobject);


#ifdef __cplusplus

}

#endif

#endif

```

注意:JNIEnv、 jobject 等类型都是在 jni.h 头文件中定义的,所以需要 include jni.h

  1. 编写步骤 3 的接口实现,创建 TestJNIImpl.c

```c

#include "jni.h"

#include "chapter01_TestJNI.h"

//#include otherheaders

JNIEXPORT void JNICALL

Javachapter01TestJNI_hello(JNIEnv *env, jobject obj)

{

printf("Helloworld!\n");

return;

}


5. 将本地方法编写的文件生成动态链接库 ```shell gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/include TestJNIImpl.c -o libhello.jnilib
复制代码


注意:如果/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/include 不存在 jni_md.h 的话,可以从 /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/include/darwin 拷贝过来

  1. 执行 java 程序

```shell

java -Djava.library.path=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/include chapter01/TestJNI

```


用户头像

awen

关注

Things happen for a reason. 2019.11.15 加入

还未添加个人简介

评论

发布
暂无评论
我看JAVA 之 Object & JNI