首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android Studio 自定义Debug变量视图的方法

Android Studio 自定义Debug变量视图的方法

作者头像
砸漏
发布2020-11-05 11:30:49
1.1K0
发布2020-11-05 11:30:49
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

我们在使用IntelliJ的IDE进行Debug时,去查看一个未重写 toString 方法的对象需要展开当前的视图层级才能看到里面的属性,而通过自定义变量视图的方式可以直接查看,很大程度上提高Debug的效率。

引出问题

我们在Debug查看变量时通常会遇到这种情况

此时我想查看 Goods 对象里面的具体属性值,需要点击左边的展开按钮才能查看里面具体的属性值,不能直接进行查看。更糟糕的是当 Goods 对象在 List 容器中时,我们如果想快速查找到当前 List 里元素的某一项(或几项)属性时,就会出现在下面的情况,我们只能逐一元素进行展开操作才能查看到元素对应的信息。

重写toString及其局限性

上述问题的一般解决方式是重写该类的 toString 方法,然后重新运行Porject,再次Debug时便可以看到变量的视图会自动变为 toString 方法的返回值,如下

这样便能无需展开直接显示 Goods 类的成员变量了,但该方式有几个缺点

  • 添加 GoodstoString 方法之后需要重新运行
  • 如果 Goods 是被依赖的 jar 这种已经被编译的只读类,则无法更改
  • 对于 Goods 中包含大量属性(比如20+个)的情况下,无法全部显示完,所以就无法根据自己的需求决定查看具体哪些属性值 自定义变量视图

IDE提供给我们一种自定义变量视图的方式,专门用来解决上面的问题并弥补了 toString 方法的不足。这里会有个 变量解析器 的概念,它用来控制当前变量的显示值(即debug时显示在该变量后面的内容,下称”变量视图”)。

首先Debug状态下右击变量,选择 Customize Data Views

接下来在 Customize Data Views 弹窗的Tab中选择 Java Type Renderers 项,如下

点击 + 来添加一个自定义的 变量解析器

自定义一个 变量解析器 ,主要需要添加的是名称、解析类型和解析方式三部分。

名称:该解析器的标识名称

解析类型:表示当前的解析器只对哪种类型的类进行解析

解析方式:此处是核心部分,可以写一个Java表达式,也可以写一段代码,这里的返回值就是该变量视图

我们可以在IDE中添加多个 变量解析器 ,通过控制它的开启、禁用、顺序、适用类等来控制当前变量的显示情况,下面进行一次完整的操作流程演示

通过自定义 变量解析器 的好处是不需要重新运行整个Project;而且还可以在Debug期间动态切换变量视图,比如

  • 查看 name 属性时: "name: " + getName()
  • 查看 type 属性时: "type: " + getType()
  • 查看 title 属性时: "title: " + getTitle()
  • ……

再进一步抽象

看了官网的自定义Debug变量视图这部分介绍后,感觉着实对于Debug很实用,通过自实现的方式使得开发者能够动态化控制变量视图。

自定义 变量解析器 的方式已经能够解决开篇提到的问题,但我更希望能通过它来找到控制变量视图的通法,即写一个通用的 变量解析器 而不是每debug一种类型的变量就单独添加一个解析器。接下来要做的事情很清楚了,就是添加一个能够将对象实例序列化成字符串的方法即可。最先想到的是通过Json进行转化,但Json一般依赖三方包,而我们想让Debug功能能够跟IDE是统一基准线的,所以尽可能选择使用Jdk自带的api。

于是考虑到了反射,对于一般通用的变量视图,我们可以直接通过反射取到每个属性名,然后结合当前实例来获取属性值,直接在上面的 解析类型 中指定为 java.lang.Object 以支持所有类型变量的解析, 解析方式 中添加下面的代码

if (((Object) this) instanceof String
    || ((Object) this) instanceof Number
    || ((Object) this) instanceof Class) {
  return ((Object) this);
}
StringBuilder sb = new StringBuilder("{");
Class<?  cls = ((Object) this).getClass();
java.lang.reflect.Field[] fields = cls.getDeclaredFields();
if (fields != null) {
  int size = fields.length;
  for (java.lang.reflect.Field field : fields) {
    field.setAccessible(true);
    Object value = field.get((Object) this);
    sb.append(field.getName())
        .append("=")
        .append(String.valueOf(value));
    if (--size   0) {
      sb.append(", ");
    }
  }
}
return sb.append("}").toString();

添加完毕之后,会发现此时我们的IDE在Debug时异常强大,所有类型的变量视图均自动转化成 key-value 形式的字符串,再也不用为了Debug变量而重写 toString 方法。看下Debug的效果

这里的 UserGoods 类均没有重写 toString 方法,但都能通过上面添加的通用解析器来进行变量视图解析。

以上就是本文的全部内容,希望对大家的学习有所帮助。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档