我看JAVA 之 Object & JNI

简介: 我看JAVA 之 Object & JNI Object Object类是java语言中所有类的父类。 public class Object { //注册本地函数,方可以从库中的本机代码调用JNI函数 private static native void registerNat.

我看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程序

    package chapter01;
    
    public class TestJNI {
    
        public native void hello();//所有native关键词修饰的都是对本地的声明
        static {
            System.loadLibrary("hello");//载入本地库
        }
        public static void main(String[] args) {
            new TestJNI().hello();
        }
    }
  2. 编译javac chapter01/TestJNI.java,生成TestJNI.class
  3. 执行javac chapter01/TestJNI.java -h . ,生成JAVA本地接口chapter01_TestJNI.h

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class chapter01_TestJNI */
    
    #ifndef _Included_chapter01_TestJNI
    #define _Included_chapter01_TestJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     chapter01_TestJNI
     * Method:    hello
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_chapter01_TestJNI_hello
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

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

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

    #include "jni.h"
    #include "chapter01_TestJNI.h"
     
    //#include otherheaders
     
    JNIEXPORT void JNICALL
    Java_chapter01_TestJNI_hello(JNIEnv *env, jobject obj)
    {
        printf("Helloworld!\n");
        return;
    }
  5. 将本地方法编写的文件生成动态链接库

    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 拷贝过来

  6. 执行java程序

    java -Djava.library.path=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/include chapter01/TestJNI
相关文章
|
3天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
28 4
|
1月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
|
2月前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
62 11
|
2月前
|
安全 Java API
【本地与Java无缝对接】JDK 22外部函数和内存API:JNI终结者,性能与安全双提升!
【9月更文挑战第6天】JDK 22的外部函数和内存API无疑是Java编程语言发展史上的一个重要里程碑。它不仅解决了JNI的诸多局限和挑战,还为Java与本地代码的互操作提供了更加高效、安全和简洁的解决方案。随着FFM API的逐渐成熟和完善,我们有理由相信,Java将在更多领域展现出其强大的生命力和竞争力。让我们共同期待Java编程新纪元的到来!
93 11
|
3月前
|
Java
【Java基础面试二十】、介绍一下Object类中的方法
这篇文章介绍了Java中Object类的常用方法,包括`getClass()`、`equals()`、`hashCode()`、`toString()`、`wait()`、`notify()`、`notifyAll()`和`clone()`,并提到了不推荐使用的`finalize()`方法。
【Java基础面试二十】、介绍一下Object类中的方法
|
3月前
|
JSON 前端开发 Java
java系列之 页面打印出 [object Object],[object Object]
文章解释了在前端页面打印JSON对象时出现`[object Object]`的原因,并提供了使用`JSON.stringify(json对象)`方法将对象转换为可读字符串的解决方案。
java系列之 页面打印出 [object Object],[object Object]
|
3月前
|
前端开发 Java 编译器
【前端学java】java中的Object类和前端中的Object有什么区别(9)
【8月更文挑战第10天】java中的Object类和前端中的Object有什么区别
40 0
【前端学java】java中的Object类和前端中的Object有什么区别(9)
|
3月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
35 5
|
3月前
|
开发框架 Java Android开发
JNI中调用Java函数
JNI中调用Java函数
25 0
|
3月前
|
开发框架 Java Android开发
JNI中调用Java函数
JNI中调用Java函数
31 0