JDK8阅读笔记(一)java-lang:Object

296 阅读3分钟

Object类是Java所有类的父类,至少我读其它源码前是这样理解的。Java里面加载类时,会检测对应类的class文件格式以及对应版本,检查无误后会通过双亲委托机制向上遍历父类,最终会找到父类Object。

1. 源码

java.lang.Object类源码如下:


public class Object {

    private static native void registerNatives();
    static {
        registerNatives();
    }
    public final native Class<?> getClass();
    public native int hashCode();
    public boolean equals(Object obj) {
        return (this == obj);
    }
    protected native Object clone() throws CloneNotSupportedException;
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    public final native void notify();
    public final native void notifyAll();
    public final native void wait(long timeout) throws InterruptedException;
    public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
            timeout++;
        }

        wait(timeout);
    }
    public final void wait() throws InterruptedException {
        wait(0);
    }
    protected void finalize() throws Throwable { }
}

其中,有一个声明为native的方法,该方法没有方法体,只有声明。

2. Native关键字

native关键字即 JNI(Java Native Interface),用于声明原生方法,编译时会与本地C代码交互。native 关键字告诉编译器(JVM)调用的是该方法在外部定义C代码(windows下是dll)。

.dll,动态链接库英文为DLL,是Dynamic Link Library的缩写。DLL是一个包含可由多个程序,同时使用的代码和数据的库。

java代码检索dll会查询java.library.path参数,该参数的查询方式:

java -XshowSettings:properties -version

或者

public class Test {
    public static void main(String[] args) {
        System.out.println(System.getProperty("java.library.path"));
    }
}

JAVA调用C代码的流程:

  • Java中声明native()方法,然后编译;用javah产生一个.h文件
  • 编写C代码、添加产生的头文件以及jni.h文件;
  • 编译成动态链接库文件(DLL);
  • Java中使用System.loadLibrary()方法加载DLL文件,从而被jvm中其它代码段使用

3. 相关方法

    /** 
     * 获取类信息
     * 实际的结果类型是Class<? extends |X|>,其中|X| 是擦除后的静态类型
     */
    public final native Class<?> getClass();
    // 比较哈希码
    public native int hashCode();
	
    /**
     * 比较对象
     * 一般会先调用hashCode方法
     * 特性:自反、对称、可传递、一致
     * 每当重写此方法时,通常都需要重写hashCode方法,以维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希码
     */
    public boolean equals(Object obj);
	
    /**
     * 克隆对象。此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作
     * 如果该对象的类没有实现接口Cloneable ,则抛出CloneNotSupportedException
     * 类Object本身不实现接口Cloneable ,因此在类为Object的对象上调用clone方法将导致在运行时抛出异常。
     */
    protected native Object clone() throws CloneNotSupportedException;
    
    /**
     * 打印文本
     * 该方法返回一个字符串,该字符串由对象是其实例的类的名称、at符号“ @ ”和对象哈希码的无符号十六进制表示组成:
     *       getClass().getName() + '@' + Integer.toHexString
     */
    public String toString();
    
    /**
     *notify唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。
     *notifyAll 会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现
     */
    public final native void notify();
    public final native void notifyAll();
    // wait用于挂起线程,会释放线程锁
    public final native void wait(long timeout) throws InterruptedException;
    public final void wait(long timeout, int nanos) throws InterruptedException;
    public final void wait() throws InterruptedException
    /**
     * 用于释放内存空间
     * 当一个堆空间中的对象没有被栈空间变量指向的时候,这个对象会等待被java回收
     */
    protected void finalize() throws Throwable { }

4. java.lang.Void

Void类是一个不可实例化的占位符类,用于保存对表示 Java 关键字 void 的Class对象的引用。

public final class Void {

    /**
     * 表示与关键字void对应的伪类型的Class对象。
     */
    @SuppressWarnings("unchecked")
    public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");
    /*
     * Void类无法实例化.
     */
    private Void() {}
}
  1. 相关

如何修复 JNI 项目中的 UnsatisfiedLinkError(找不到依赖库)