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. 【译】理解JavaScript闭包——新手指南

    闭包是JavaScript中一个基本的概念,每个JavaScript开发者都应该知道和理解的.然而,很多新手JavaScript开发者对这个概念还是很困惑的. 正确理解闭包可以帮助你写出更好.更高效. ...

  2. 基于bootstrap的jQuery多级列表树插件 treeview

    http://www.cnblogs.com/mfc-itblog/p/5233453.html http://www.htmleaf.com/jQuery/Menu-Navigation/20150 ...

  3. python全栈开发day76-博客主页

    一.昨日内容 1. 注册 1. form组件 - 基于正则的校验规则(手机号和邮箱) - 基于全局钩子判断两次密码是否一致 2. $.each(遍历的对象, function(){ this --&g ...

  4. mybatis拦截器处理

    1.自定义注释 package com.hsfw.backyard.biz.security.authority; import java.lang.annotation.*; /** * 数据权限过 ...

  5. nginx配置2

    第四节 nginx 配置文件 1 keepalive_timeout   65;  设定保存长久连接时长 0代表禁止, 若不设置默认是75s 2keepalive_requests   nu;  在一 ...

  6. User模型扩展和自定义

    参考如下: django文档参考 django signal使用总结 django 信号注册 django信号问题1 django oneTooneFiled     1. django 自定义用户u ...

  7. HDU4466 Triangle 计数 容斥原理

    原文链接https://www.cnblogs.com/zhouzhendong/p/HDU4466.html 题目传送门 - HDU4466 题意 多组数据,每次询问一个数 $n(n\leq 5\t ...

  8. 058 kafka与log4j集成

    1.首先在resources下面写log4j.properties 主要是因为kafka.producer.KafkaLog4jAppender类的存在. log4j.rootLogger=INFO, ...

  9. radio按钮单选效果

    必须有name,并且是同一值,判断效果可用value值确定

  10. 实验吧debug

    在linux下进行调试时容易出现权限不够的情况:此时解决办法就是chmod 777+文件名提升权限,以实验吧debug为例,给出了简单的32elf文件,我在查看一些资料以后发现,我需要在main函数处 ...