So erhalten Sie eine Objektinstanz einer Klasse

Wie erhalte ich eine Objektinstanz einer Java-Klasse? Diese Klasse ist nicht unbedingt ein Singleton, sie stellt auch nicht unbedingt statische Methoden bereit und wird auch nicht unbedingt von Spring verwaltet. Wie können wir alle Objektinstanzen dieser Klasse erhalten, wenn ihr Quellcode nicht einmal geändert werden kann? Hier ist eine Implementierungsmethode basierend auf JVMTI.

Gebrauchsanweisung

Zitieren Sie zunächst die Maven-Abhängigkeiten

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

Rufen Sie dann direkt die Funktion  InstancesOfClass.getInstances(Class<?> targetClass) auf  , um alle Objektinstanzen einer Klasse abzurufen

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

Umsetzungsprinzip

In Java gibt es keine Schnittstelle zum Abrufen von Instanzen basierend auf Klassen. Sie müssen die JVMTI-Schnittstellen IterateOverInstancesOfClass und GetObjectsWithTags verwenden.

Schreiben Sie zunächst eine Klasse mit nativen Methoden

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

Verwenden Sie dann Javah, um die .h-Datei zu generieren, und verwenden Sie dann C++, um den Implementierungsteil zu schreiben.

#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;
}

 

Verwenden Sie dann gcc/g++, um den CPP-Quellcode zu kompilieren und die entsprechenden dynamischen Linkbibliotheksdateien unter Linux/Mac/Windows zu generieren. Laden Sie also .dylib und .dll die entsprechenden lokalen Linkbibliotheken über System.load () und rufen Sie sie schließlich auf InstancesOfClass.getInstances(Class <?> targetClass)  -Methode.

Den detaillierten Quellcode finden Sie unter  https://github.com/Liubsyy/FindInstancesOfClass , der Testfälle enthält.

 

 

 

 

Lei Jun kündigte die komplette Systemarchitektur von Xiaomis ThePaper OS an und sagte, dass die unterste Schicht komplett neu strukturiert wurde. Yuque gab am 23. Oktober die Ursache des Ausfalls und den Reparaturprozess bekannt. Microsoft-CEO Nadella: Der Verzicht auf Windows Phone und das Mobilfunkgeschäft war eine falsche Entscheidung . Sowohl die Nutzungsraten von Java 11 als auch von Java 17 überstiegen den Zugriff von Java 8 Hugging Face auf Yuque. Der Netzwerkausfall dauerte etwa 10 Stunden und hat sich nun wieder normalisiert. Die National Data Administration hat Oracle offiziell vorgestellt. Java-Entwicklungserweiterung für Visual Studio gestartet Code. Musk: Spenden Sie 1 Milliarde, wenn Wikipedia in „Weiji Encyclopedia“ umbenannt wird. USDMySQL 8.2.0 GA
{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/u/3276866/blog/10123262
Empfohlen
Rangfolge