• 0
  • 0
分享
  • Groovy StringBuilder类踩坑
  • FunTeste 2023-12-06 21:35:53 字数 3485 阅读 933 收藏 0

今天在写脚本的时候发现一个奇怪的错误。经过猜想验证,发现原来Groovy过于灵活了,算是重复踩了之前的坑。Groovy特性描述如下:


当Groovy脚本调用getFun()和setFun()方法时,会默认给这个类有一个FunTester的属性。反过来,如果这个类有Fun这个属性,那么get和set方法是不用显式写出来的。


本来这是个好事情,一方面其实可以免去多余代码,一方面更容易收拢入口方法(因为直接访问属性、修改属性也是有限调用get和set方法)。


但是就是这个特性让我下面的代码报错了。


```

        StringBuilder sb = new StringBuilder()

        for (int i = 0; i < 3; i++) {

            sb.append("a" + i)

            output(sb.toString())

            sb.setLength(0)

        }


```


其中java.lang.AbstractStringBuilder#setLength方法是用来裁剪StringBuilder对象内容的,如果参数为0,实际的功效就是清空。


官方的描述为:


`setLength(int newLength)` 是 `AbstractStringBuilder` 类中的一个方法,用于设置字符串的长度。具体来说,它有以下作用:


- 如果 `newLength` 小于当前字符串的长度,则字符串将被截断为指定的长度 `newLength`。

- 如果 `newLength` 大于当前字符串的长度,则在字符串末尾填充空字符('\0')直到字符串达到指定的长度 `newLength`。


下面是我代码报错信息:


```

No signature of method: java.lang.StringBuilder.setLength() is applicable for argument types: (Integer) values: [0]

at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:70)

at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)

```


错误信息显示并没有这个方法,真是见了鬼了,我在Intellij里面查看源码时明明显示没有问题。当我把问题抛给ChatGPT,得到如下回答。


  

这个错误信息是Groovy中的一个问题,可能是因为Groovy与Java在`StringBuilder`类的操作上存在某些不同。`setLength()`方法通常用于设置`StringBuilder`的长度,但是错误信息表明`setLength()`方法似乎被错误地调用,传递了一个不正确的参数类型。在Java中,`setLength()`方法接受一个`int`类型的参数,表示要设置的新长度。但是在错误信息中显示传递了`Integer`类型的值 `[0]`,这可能导致方法调用失败。如果问题仍然存在,可能需要进一步检查Groovy代码中的其他部分,以确保在`StringBuilder`操作方面没有其他的语法错误或问题。


这个时候我才意识到这是一个Groovy的报错,并不是Java的。所以,根据我多年踩坑经验早就的敏感度,set方法一定是出问题了。经过我检查,StringBuilder类并没有length属性,这就是导致报错的根本原因。


下面我来验证自己的猜想,通过Groovy元编程给StringBuilder类加上这个length属性。


```

        StringBuilder.metaClass.length= 32

        StringBuilder sb = new StringBuilder()

        for (int i = 0; i < 3; i++) {

            sb.append("a" + i)

            output(sb.toString())

            sb.setLength(0)

        }

```


这下不报错了,但问题来了,setLength功能不起作用了,因为优先去设置属性值去了。看来虽然验证了,但是功能破坏了,只好用点笨办法了。


```

        StringBuilder.metaClass.length= 32

        StringBuilder sb = new StringBuilder()

        for (int i = 0; i < 3; i++) {

            sb.append("a" + i)

            output(sb.toString())

        }

```



这个就解决了所有问题。当我去用Java代码中验证时,发现一直没有报错。我换了个项目(Maven/Gradle)结果发现居然无法复现了。哎,又遇到幽灵的问题,可能Groovy在编译这个项目类的时候开小差了。我的JDK版本17,Groovy编译插件版本3.0.1,重新清空本地缓存重启Intellij也依然如此。

通过对比两个项目差异,同时升级Groovy依赖版本和编译插件版本,改缺陷自动解决了。


> - [900原创合集](https://mp.weixin.qq.com/s/lDZ344i0N_red3zy06MRLw)

> - [2021年原创合集](https://mp.weixin.qq.com/s/ziuOuueP6tN2U7dF06axkw)

> - [2022年原创合集](https://mp.weixin.qq.com/s/Ztet8pky58B8RBLWrqdrpg)

> - [接口功能测试专题](https://mp.weixin.qq.com/s/yp4Y0RHmGsozxWzPAL4SXw)

> - [性能测试专题](https://mp.weixin.qq.com/s/0PJGfWT49rkw2uRbcezf4w)

> - [Groovy专题](https://mp.weixin.qq.com/s/wsk4ggKoRiqkQqL7uN9dPg)

> - [Java、Groovy、Go、Python](https://mp.weixin.qq.com/s/LrcAe7M6dUigysM01RpvkQ)

> - [单测&白盒](https://mp.weixin.qq.com/s/IK1aF4ScRE8qRhbEULBzgA)

> - [FunTester社群风采](https://mp.weixin.qq.com/s/bBJUgwOwJv3veRwVkVVfqQ)

> - [测试理论鸡汤](https://mp.weixin.qq.com/s/67jXEMIJZQZ_EMW2tSJsBA)

> - [FunTester视频专题](https://mp.weixin.qq.com/s/Z6wacRieYeJJSEDxj8_S-A)

> - [案例分享:方案、BUG、爬虫](https://mp.weixin.qq.com/s/5nFwT0ACYmIHXfP9HYSZWg)

> - [UI自动化专题](https://mp.weixin.qq.com/s/AnefdNf8izkkpmPxNphhQg)

> - [测试工具专题](https://mp.weixin.qq.com/s/2PkPIaCFGOPCUP2P44a2iw)


  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 读者提问:测试管理如何做到灵活调度测试资源 ?阿常回答:我在企业中的做法,供参考,有不同观点欢迎讨论。如何做到灵活调度测试资源1 将团队按业务线分成几个小组根据不同的业务线划分不同的测试小组;每个测试小组2~3人不等,每个小组指定一个leader;小组leader尽量不做变动,其他成员可根据具体不同业务的迭代任务量来做资源调度。2 周例会各业务组分享测试经验每周安排例行的业务测试经验分享;分享内容选取各业务线的重点业务;分享者为各业务测试小组的测试同学。3 各小组到其他业务组交叉测试在某个业务组需求任务较重时,从其他业务组调度测试资源;在各业务组同期迭代任务都较少的情况,安排各业务组进行交叉测...
            0 0 863
            分享
          • 什么是网络爬虫?相信刚接触爬虫这个词的人都有这样的疑问,网络爬虫可以做什么?它是基于什么样的原理,如果想要学习爬虫,需要掌握什么知识。本文将会对这些问题做一个解释和说明,希望可以帮助正在爬虫入门阶段的朋友。网络爬虫是捜索引擎抓取系统的重要组成部分,爬虫的主要目的是将互联网上的网页下载到本地形成一个互联网内容的镜像备份那么网络爬虫的基本结构和工作流程是什么样的呢?基本的工作流程如下:首先可以选择一部分精心挑选的种子url;将这些URL放入待抓取URL系列;从待抓取URL队列中取出待抓取在URL,解析DNS,并且得到主机的ip,并将URL对应的网页下载下来,存储进已下载网页库中。此外,将这些URL...
            12 12 1809
            分享
          •   经常会遇到一些面试官没事的时候问,为什么选择软件测试?  我都在这个行业,你怎么还问我为什么选择软件测试?  错误回答一:我觉得软件测试收入较高。  我们都知道软件测试收入是很高,但是这也不是你面试回答的点啊  行业收入高不高大家都知道,不应该成为你面试的回答点和你被录用的原因!!!  错误回答二:我觉得软件测试比较简单,好入门。  这个回答你想表达什么?  对你的面试有什么好处?  体现你没本事,就会做简单的吗?  多余的就不说了,我们来说说什么叫好的回答  经典回答一:  我大学期间就对软件很感兴趣,并且也了解到软件测试是一个非常细致的工作,我自己本身也是一个很细致的人,就专门自学了软...
            0 0 319
            分享
          •   苹果和亚马逊在 2018 年达成了协议,苹果终于建立了亚马逊官方店面,为此,两家公司再次面临审查。Insider 今天的一篇报道深入探讨了这一协议的细节,一位消息人士称,苹果正从亚马逊那里获得"大量优惠待遇"。  在过去的几年里,苹果和亚马逊之间的交易一直面临着监管部门的强烈反对。这两家公司还在与一起价格垄断诉讼作斗争,该诉讼指控它们合谋提高 iPhone 和 iPad 的价格。  正如今天的报道所详述的,苹果和亚马逊之间的协议包括一项例外条款,即减少出现在苹果设备产品页面上的广告和推荐数量。亚马逊的产品页面一般都充斥着广告、赞助商结果和推荐,而苹果的产品页面只在页面最...
            0 0 975
            分享
          •   从去年决定跳出舒适区,应聘大厂,截止到目前已经将近一年,值此之际,总结下自己近一年在大厂的经历。  希望通过我的感触,能够帮助你们进一步了解大厂的测试工作。  维护上下游合作关系  在大厂,人际关系非常重要,为什么要把它放在第一位,是因为在大厂里做测试的时候,所涉及的系统错综复杂,种类繁多,经常要进行上下游的联调测试。  我刚开始的时候,测试联调找不到相关的责任人,使得自己在测试工作中浪费了大量的时间和精力,所以进入大厂之后,一定先要:  首先,梳理自己负责系统的上下游联系人,将其联系方式整理起来,方便后续查询联络,可以参考下面表格进行简单汇总即可。  其次,维护好自己与前辈的关系,保持自...
            12 12 1691
            分享
      • 51testing软件测试圈微信