クラスのオブジェクトインスタンスを取得する方法

Java クラスのオブジェクト インスタンスを取得するにはどうすればよいですか? このクラスは、必ずしもシングルトンである必要はなく、静的メソッドを提供する必要も、Spring によって管理される必要もありません。ソース コードを変更することさえできない場合、どのようにしてこのクラスのすべてのオブジェクト インスタンスを取得できるでしょうか? JVMTIをベースにした実装方法を紹介します

使用説明書

Maven の依存関係を最初に引用します

<dependency>
   <groupId>io.github.liubsyy</groupId>
  <artifactId>FindInstancesOfClass</artifactId>
   <version>1.0.1</version>
</dependency>

次に、関数 InstancesOfClass.getInstances(Class<?> targetClass)を直接呼び出して 、クラスのすべてのオブジェクト インスタンスを取得します。

public class InstancesOfClass {
    /**
     * native方法 : 返回所有的实例对象
     * @param targetClass 需要查询实例的Class
     * @return
     */
    public static native Object[] getInstances(Class<?> targetClass);
}

実施原則

Java にはクラスに基づいてインスタンスを取得するためのインターフェイスがないため、JVMTI インターフェイスの IterateOverInstancesOfClass および GetObjectsWithTags を使用する必要があります。

まずネイティブ メソッドを含むクラスを作成します

public class InstancesOfClass {
    /**
     * native方法 : 返回所有的实例对象
     * @param targetClass 需要查询实例的Class
     * @return
     */
    public static native Object[] getInstances(Class<?> targetClass);
}

次に、javah を使用して .h ファイルを生成し、C++ を使用して実装部分を作成します。

#include <jni.h>
#include <jvmti.h>
#include "com_liubs_findinstances_jvmti_InstancesOfClass.h"


static jvmtiIterationControl JNICALL objectInstanceCallback(jlong class_tag, jlong size, jlong* tag_ptr, void* user_data) {
    *tag_ptr = 1;
    return JVMTI_ITERATION_CONTINUE;
}

JNIEXPORT jobjectArray JNICALL Java_com_liubs_findinstances_jvmti_InstancesOfClass_getInstances(JNIEnv* env, jclass clazz, jclass targetClazz) {
    JavaVM* vm;
    env->GetJavaVM(&vm);

    jvmtiEnv* jvmti;
    vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);

    jvmtiCapabilities capabilities = {0};
    capabilities.can_tag_objects = 1;
    jvmti->AddCapabilities(&capabilities);

    jvmti->IterateOverInstancesOfClass(targetClazz, JVMTI_HEAP_OBJECT_EITHER,
                                       objectInstanceCallback, NULL);

    jlong tag = 1;
    jint count;
    jobject* instances;
    jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);

    printf("Found %d objects with tag\n", count);

    // 转换jobject* 为 jobjectArray 并返回
    jobjectArray result = env->NewObjectArray(count, targetClazz, NULL);
    for (int i = 0; i < count; i++) {
        env->SetObjectArrayElement(result, i, instances[i]);
    }

    jvmti->Deallocate((unsigned char*)instances);
    return result;
}

 

次に、gcc/g++ を使用して cpp ソース コードをコンパイルし、対応するダイナミック リンク ライブラリ ファイルを linux/mac/windows に生成します。そのため、.dylib と .dll を使用して、System.load() を介して対応するローカル リンク ライブラリをロードし、最後に呼び出します。 InstancesOfClass.getInstances(Class <?> targetClass) メソッド。

詳細なソース コードについては、 テスト ケースが含まれているhttps://github.com/Liubsyy/FindInstancesOfClassを参照してください。

 

 

 

 

Lei Jun氏はXiaomiのThePaper OSの完全なシステムアーキテクチャを発表し、最下層が完全に再構築されたと述べ、 Yuque氏は10月23日に障害の原因と修復プロセスを発表 Microsoft CEOのナデラ氏「Windows Phoneとモバイル事業を放棄したのは間違った決断だった」 . Java 11 と Java 17 の使用率は両方とも Java 8 を上回りました. Hugging Face は Yuque へのアクセスを制限されました. ネットワーク障害は約 10 時間続きましたが、現在は通常に戻っています. 国家データ局が Oracle を正式に発表しました. Visual Studio 用の Java 開発拡張機能を開始しましたCode.Musk : Wikipedia が「Weiji Encyclopedia」に名前変更されたら 10 億寄付 USDMySQL 8.2.0 GA
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/3276866/blog/10123262