Keywords: Groovy, Reflection, 反射

The Reflection of Groovy String constant style method.

Groovy支持以下的方法定义:

class A {
def "I am a method"() {
}
}

Groovy是继承Java的机制的,而Java显然是不支持这种函数定义命名的。然而实际上,你是用A.class.getMethods() 或 A.metaClass.getMethods() 都能获取到带空格的方法名,只是调用起来很麻烦,可能只能靠反射去invoke调用。所以一般这种写法主要用于TestSuite做单元测试或测试驱动开发。其实这个反射很简单,难的是下面的。

Spock是个很灵活的Java/Groovy的测试框架(Spock以后有空再介绍),基于JUnit。但是Spock中继承了Specfication的测试类的字符串常量方法,会在groovy compile的时候compile成一个名字类似$spock_feature_0_0 这样的名字,这时候想要找回原来的对应的常量就不是那么简单了。但既然JUnit能做到,我们就去看JUnit的run的源码,发现它会生成一个Sputnik的Runner,这是个Spock的类,其中它会有个private的SpecInfo的字段,里面包含了当前类的所有features。Spock把每个test method看作一个feature。

因此我只要new一个Sputnik,通过反射把SpecInfo中的信息拿出来,就能拿到按顺序所有排序的方法和对应编译后的方法名了了。

 public static List<String> getAllSpecFeatures(String className) {
List<String> ret = new ArrayList<>();
Class klass = Class.forName(className);
Sputnik runner = new Sputnik(klass);
Method m = runner.class.getDeclaredMethod("getSpec");
m.setAccessible(true);
SpecInfo specInfo = m.invoke(runner);
List<FeatureInfo> featureInfos = specInfo.getAllFeatures();
for (FeatureInfo featureInfo : featureInfos) {
// original groovy method name
ret.add(featureInfo.getName()); // compiled method name, format like "$spock_feature_0_0"
println(featureInfo.featureMethod.reflection.name)
}
return ret;
}

Groovy 反射字符串常量方法的更多相关文章

  1. 字符串常量池和String.intern()方法在jdk1.6、1.7、1.8中的变化

    字符串常量池也是运行时常量池 jdk1.6中,它是在方法区中,属于“永久代” jdk1.7中,它被移除方法区,放在java堆中 jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了 pub ...

  2. java中字符串“不可变性”的破坏,使用反射破坏final属性。以及涉及到字符串常量池的问题。

    大家都清楚java中String类是不可变的,它的定义中包含final关键字.一旦被创建,值就不能被改变(引用是可以改变的). 但这种“不可变性”不是完全可靠的,可以通过反射机制破坏.参考一下代码: ...

  3. Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能

    Java中Pattern类的quote方法将任何字符串(包括正则表达式)都转换成字符串常量,不具有任何匹配功能. 下面是个例子: import org.junit.Test; import java. ...

  4. 对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法

    在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普 ...

  5. 理解Java字符串常量池与intern()方法

    String s1 = "Hello"; String s2 = "Hello"; String s3 = "Hel" + "lo ...

  6. Java 字符串常量存放在堆内存还是JAVA方法区?

    JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池. JDK1.8开始,取消了Java方法区,取而代之的是位于直接内 ...

  7. 从HotSpot VM源码看字符串常量池(StringTable)和intern()方法

    引言 字符串常量池(StringTable)是JVM中一个重要的结构,它有助于避免重复创建相同内容的String对象.那么StringTable是怎么实现的?"把字符串加入到字符串常量池中& ...

  8. 在JavaScript里嵌入大量字符串常量的方法

    [转]在JavaScript文件里嵌入大量字符串常量是经常遇到的事.有时为了省事,就把一些界面的HTML和CSS直接写在JS文件里.数量少还好,多的话就密密麻麻的一坨文字,讲究美观的文艺青年们,会用大 ...

  9. 使用Microsoft Roslyn提取C#和VB.NET源代码中的字符串常量

    Microsoft Roslyn是微软.NET“编译器即服务(Compiler as a Service)”的主要产品,它提供了开放的编译器API,并为源代码产生.分析和重构提供了新一代的语言对象模型 ...

随机推荐

  1. [转] Mongoose简要API

    Mongoose是在node.js环境下对mongodb进行便捷操作的对象模型工具 因此,要使用mongoose,则必须安装node.js环境以及mongodb数据库.mongoose使mongodb ...

  2. raspberry pi恢复jessie镜像之后

    1.更新源 nano /etc/apt/source.list deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib ...

  3. 【前端基础系列】slice方法将类数组转换数组实现原理

    问题描述 在日常编码中会遇到将类数组对象转换为数组的问题,其中常用到的一种方式使用Array.prototype.slice()方法. 类数组对象 所谓的类数组对象,JavaScript对它们定义为: ...

  4. 【AtCoder】ARC075

    ARC075 在省选前一天听说正式选手线画到省二,有了别的女选手,慌的一批,然后刷了一个ARC来稍微找回一点代码感觉 最后还是挂分了,不开心 果然水平退化老年加重啊 原题链接 C - Bugged 直 ...

  5. rem布局js设置,设置网页文档参考字体闭包函数

    (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ...

  6. BZOJ1001 [BeiJing2006]狼抓兔子 最小割 对偶图 最短路

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686871.html 题目传送门 - BZOJ1001 题意 长成上面那样的网格图求最小割. $n,m\leq ...

  7. 事件(Event)(onclick,onchange,onload,onunload,onfocus,onblur,onselect,onmuse)【转载】

    ylbtech-Event:事件(Event)对象 事件(Event) HTML 4.0 事件属性 onclick onchange onload onunload onselect onmouse ...

  8. Excel ——多表关联查询-vlookup

    一.分组 需求: 在B列的右侧添加一列[消费分组]对B列的[月分组水平]进行分组,原始数据如下: 公式:在 C2 输入:“=VLOOKUP(B2,$E$1:$G$4,2,1)”,下拉填充. 提示:VL ...

  9. Ubuntu 装机软件

    Ubuntu16.04 软件商店闪退打不开 sudo apt-get update sudo apt-get dist-upgrade # 应该执行一下更新就好,不需要重新安装软件中心 sudo ap ...

  10. day43 mysql 基本管理,[破解密码以及用户权限设置]以及慢日志查询配置

    配置文件:详细步骤, 1,找到mysql的安装包,然后打开后会看到一个my.ini命名的程序,把它拖拽到notepad++里面来打开,(应该是其他文本形式也可以打开,可以试一下),直接拖拽即可打开该文 ...