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