興味深いJDK、オブジェクトソースコード

JDKオブジェクト

主な10の方法

1、ネイティブ registerNatives

ネイティブメソッドopenJdk1.8ソースコードは次のとおりです。

static JNINativeMethod methods[] = {
    {"hashCode",    "()I",                    (void *)&JVM_IHashCode},
    {"wait",        "(J)V",                   (void *)&JVM_MonitorWait},
    {"notify",      "()V",                    (void *)&JVM_MonitorNotify},
    {"notifyAll",   "()V",                    (void *)&JVM_MonitorNotifyAll},
    {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
};

JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
    (*env)->RegisterNatives(env, cls,
                            methods, sizeof(methods)/sizeof(methods[0]));
}

これは、Javaレイヤーのメソッド名をローカル関数に対応させます。これは、実行エンジンがバイトコードを実行するときにこれらの対応表に従ってC / C ++関数を呼び出すのに便利です。
静的JNINativeMethodメソッド[] 機能比較表

2、ネイティブ getClass

ローカルのfinalメソッド
は、このオブジェクトのランタイムクラスを返します。これは、javaのjava.lang.Classクラスに対応しています。

3、等しい

public boolean equals(Object obj) {
      return (this == obj);
}

オブジェクトが等しい場合、一般的なメソッドは特別なものではなく、メモリアドレスを直接比較します。
如果要重写equals 的话, 记得要一起重写 hashCode方法,因为要满足 equals 相等的两个对象 hashCode 值一定相等 这是来自官方的约定

4、ネイティブ ハッシュコード

 public native int hashCode();

ネイティブメソッド、書き換え可能

5、clone()

protected native Object clone() throws CloneNotSupportedException;

もう1つのローカルメソッド。自己のクローンを作成し、それを呼び出し元に返します。それは注目に値します:

  • 複製されたクラスがjava.lang.Cloneableインターフェースを継承しない場合、CloneNotSupportedExceptionがスローさ
    れます。
    public interface Cloneable {
    }
    
    次に、彼は1つの役割しかありません。彼は、オブジェクトを複製できるかどうかを決定するために使用されるマーカークラスです(jdkを設計する大物がこれを行うのはなぜですか?誰か知っていますか?)
  • cloneメソッドは、デフォルトでは浅いコピーのみです。浅いコピーとは何ですか?
    cloneメソッドは、オブジェクト内のメンバー変数を複製しません。ディープコピーを実現するには、クローンメソッドを自分で書き直す必要があります

6、toString

また、これはより一般的に使用されるメソッドです。多くの場合、クラスを文字形式に変換して印刷する必要があります。たとえば、次のコードSystem.out.printlnプログラムは、ObjectとHashMapのtoStringメソッドを自動的に呼び出します。
それでは、このコードを実行するとどのような結果が得られますか?

  1 System.out.println("1:" + new Object());

  2 Map data = new HashMap<>();
  3 data.put("k", "v");
  4 System.out.println("2:" + data);

プログラムの実行効果は次のとおりです。

1:java.lang.Object@543e710e
2:{k=v}

乱雑なキャラクターとリーズナブルなキャラクターのシリーズを手に入れました。
ObjectのtoStringソースコードは次のとおりです。

    public String toString() {
        // 规则 包路径 + @ + hashcode 的十六进制字符
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    
    /**  
    * Integer.toHexString 将十进制转为十六进制
    * 忽略具体实现
    **/
    public static String toHexString(int i) {
      return toUnsignedString0(i, 4);
    }
    
    

8. notify()notifyAll()はすべて ネイティブ ネイティブメソッド

  • 効果は似ています。オブジェクトがロックを解放するのを待機しているスレッドをウェイクアップするには、notifyAllメソッドが、オブジェクトがロックを解放するのを待機しているすべてのスレッドをウェイクアップします。
  • ロックを保持せずにこのメソッドを呼び出すと、IllegalMonitorStateExceptionがスローされます
  • 通常、待機メソッドで使用されます
  • この一連のメソッドを開発に使用することはお勧めしません。コードが非常に読みやすくなります。
  • notifyを呼び出してもすぐにはロックが解除されずに実行が継続され、同期領域を出た後にロックが解除されると、待機中のスレッドを起こします。

9、wait()wait(long timeout)wait(long timeout、int nanos)

  • ロックを保持しているオブジェクトを呼び出すと、すぐにロックが解除され、すぐにブロッキング状態になり、通知メソッドが起動するのを待ちます
  • 目覚めた後、ロック競争に再び参加する
  • wait(long timeout)wait(long timeout、int nanos)のパラメータはタイムアウト時間であり、この時間待機した後、プログラムは自動的に起動します。
    タイムアウト(ミリ秒)ナノ(微妙)
  • wait()にはパラメーターメソッドはありません。外部ウェイクアップがない場合、永久に待機します!
  • ロックを保持せずにこのメソッドを呼び出すと、IllegalMonitorStateExceptionがスローされます

10、finalize()

非常に味のない方法、推奨されません

protected void finalize() throws Throwable { }
  • ガベージコレクターこのメソッドは、リサイクルされるオブジェクトをリサイクルする前に1回呼び出されます。このオブジェクトはfinalize()をオーバーライドしていることが前提です

用途は何ですか?

  • リサイクルする前にプログラムに通知します。プログラムはfinalizeメソッドを使用して一部のリソースを回復するか、セルフヘルプを実行できます(リサイクルしたくない)。
// 拯救自己 《伪代码》
protected void finalize() throws Throwable { 
    某全局静态变量.value = this; // 自我拯救 完成,这样垃圾回收器本次将不会回收我
}
  • ただし、オブジェクトが復活できるのは1回だけであることに注意してください。ガベージコレクションプロセス中は、復活したオブジェクトに対してFinalizeを呼び出すことはできません。ガベージコレクションにより、リサイクルされるオブジェクトが復活オブジェクトであることが判明した場合、オブジェクトは直接リサイクルされます。

それをお勧めしませんか?

  • 間に合わない、やっと間に合うように試みない、ガベージコレクションの前に呼び出されるのを待つ必要がある、GCムードを参照
  • ガベージリサイクルプロセスの複雑さを増し、ガベージコレクタの効率を下げます。頻繁に使用すると、JVMのパフォーマンスの問題が発生する可能性があります
  • 呼び出し順序の保証はありません。オブジェクトの死の時とは関係ありません。
元の記事を17件公開 24 件を獲得 28万回以上表示

おすすめ

転載: blog.csdn.net/qq_22956867/article/details/89528087