您现在的位置是:首页 > 文章详情

如何获取一个类的对象实例

日期:2023-10-26点击:69

如何获取一个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

首先写一个包含native方法的类

 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下对应的动态链接库文件 .so, .dylib和.dll,通过System.load()加载对应本地链接库,最后调用InstancesOfClass.getInstances(Class<?> targetClass) 方法即可。

具体源码详见 https://github.com/Liubsyy/FindInstancesOfClass,里面包含了测试用例

 

 

 

 

原文链接:https://my.oschina.net/u/3276866/blog/10123262
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章