如何获取一个类的对象实例
如何获取一个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,里面包含了测试用例

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
智能问答技术在百度搜索中的应用
作者 | Xiaodong 导读 本文主要介绍了智能问答技术在百度搜索中的应用。包括机器问答的发展历程、生成式问答、百度搜索智能问答应用。欢迎大家加入百度搜索团队,共同探索智能问答技术的发展方向,文末有简历投递方式。 全文6474字,预计阅读时间17分钟。 01 什么是机器问答 机器问答,就是让计算机软件系统自动回答人类提出的描述性问题。例如问:“王小丫的主持的节目叫什么”,我们可以在百度搜索框里输入任意用自然语言描述的问题,并在搜索的首位结果中可以直接得相关答案,如下图所示: 区别于传统搜索引擎根据多个关键词反馈检索的网页链接,机器问答根据自然语言描述的问题直接获取答案,可以极大地提高大家获取信息的效率。机器问答在生活中无处不在,经统计,有约40%的搜索需求、约30%的对话需求都跟机器问答相关。 那么,百度搜索的机器问答应用现状如何?目前首条结果可以直接满足大部分的问答需求,并且,在百度搜索中,不限定用户问题领域,是一个开放式的问答系统,可以询问任何信息。 1.1 机器问答的发展历程 机器问答的发展历程如下,与机器学习发展相吻合。 从模型方法的发展上看: 2013年以前,大家主要做一...
- 下一篇
【ssh 客户端】tssh 发布 v0.1.12 支持自动重连
【ssh 客户端】tssh 发布 v0.1.12,支持 --reconnect 自动重连;记住密码的功能支持加密密码,防止被窥屏;支持更多功能,详见文档。 GitHub:https://github.com/trzsz/trzsz-ssh tssh 简介 你喜欢的 ssh 终端是否有好用的服务器管理功能?是否支持记住密码?是否有好用的文件传输工具? tssh 支持选择或搜索~/.ssh/config中配置的服务器,支持 vim 操作习惯,解决 ssh 终端的服务器管理问题。 tssh 支持一次选择多台服务器,批量登录,并支持批量执行预先指定的命令,方便快速完成批量服务器操作。 tssh 支持配置服务器登录密码,解决每次手工输入密码的麻烦( 在自己能控制的服务器,推荐使用公私钥登录 )。 tssh 内置支持trzsz(trz /tsz) 文件传输工具,一并解决了 Windows 中使用trzsz ssh上传速度很慢的问题。 在作者的 MacOS 上,使用trzsz ssh的上传速度在 10 MB/s 左右,而使用tssh可以到 80 MB/s 以上。 安装方法 客户端安装trzsz-ss...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS7,CentOS8安装Elasticsearch6.8.6