Groovy 反射字符串常量方法

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.getFeatures();
        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;
    }
时间: 2024-10-25 23:04:47

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

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

在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普遍的时候),类几乎是"静态的"并且很少被卸载和回收,因此类也可以被看成"永久的".另外由于类作为JVM实现的一部分,它们不由程序来创建,因为它们也被认为是"非堆"的内存. 在JDK8之前的HotSpot虚拟机中,类的这些"永久的"

C# 通过反射执行已存在于类中的方法 通过字符串执行方法

通过字符串执行方法,在可能会调用不同方法时对不同方法进行调用 以下为实例: 1 public class ABC 2 { 3 string str = "通过反射执行的方法"; 4 //Class:要反射的Method所在类名 5 Type type = typeof(Class); 6 //funcName:进行反射的方法名称,第二个参数指定方法的搜索范围,当前为搜索private的方法,没有第二个参数则为public的方法 7 MethodInfo mt = type.GetMet

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

[转]在JavaScript文件里嵌入大量字符串常量是经常遇到的事.有时为了省事,就把一些界面的HTML和CSS直接写在JS文件里.数量少还好,多的话就密密麻麻的一坨文字,讲究美观的文艺青年们,会用大量的字符连接符号甚至加上缩进,强制换成好几行.例如: var html = '<div>' + '<p>Hello</p>' + '<p>World'</p>' + '</div>'; 这还好,要是字符串里有不少双引号单引号,那就更麻烦了

Java中的字符串常量池

最近做到一个题目: 问题:String str = new String("abc"),"abc"在内存中是怎么分配的?    答案是:堆,字符串常量区. 题目考查的为Java中的字符串常量池和JVM运行时数据区的相关概念."abc"为字面量对象,其存储在堆内存中.而字符串常量池则存储的是字符串对象的一个引用. Java中的字符串常量池 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid&qu

string字符串常量池在内存中的位置

这里仅仅是举个简单的样例说明字符串常量池在内存中的位置. 闲言少叙,直接上代码. Java代码   <span style="font-size: large;">import java.util.ArrayList; public class Test { public static void main(String[] args) { String str = "abc"; char[] array = {'a', 'b', 'c'}; String

java字符常量与字符串常量的区别

形式上:字符常量是单引号引起的一个字符例:‘a’字符串常量是双引号引起的若干个字符"helloworld"含义上:字符常量相当于一个整形值(ASC||值),可以参加表达式运算,直接拿变量使用字符串常量代表一个地址值(该字符在内存中存放的位置)占内存大小:字符常量只占一个字节字符串常量占若干个字节字符型常量使用char型变量来存储字符串用char型的数组来存储 类型字符类型为char,字符串类型为string两者都是常量,区别于使用方法的不同

通过字符串映射方法

有时候我们需要通过类名来生成相应类的实例,这就用到反射机制. 首先通过类名生成Class类实例 在通过该Class 实例来创建(alloc)对象; 具体方法会用到  NSClassFromString(类名) 一看就知道是C语言的东西: NSString * tempClassName = @"yourClassName"; Class * tempClass =  NSClassFromString(tempClassName); 这里 在创建这个类实例之前 最好判断下 是否该对象存

Python学习总结4:字符串常量与操作汇总

参考博客:http://www.cnblogs.com/Camilo/archive/2013/09/21/3332267.html http://www.cnblogs.com/SunWentao/archive/2008/06/19/1225690.html 1. 字符串常量 string.digits:包含0-9的字符串    string.letters:包含所有大小写字母的字符串     string.lowercase:所有小写字母    string.printable:包含所有可

字符串常量池、堆、栈

String a="a"+"b"+"c" 创建了几个对象 这个问题涉及到了字符串常量池和字符串拼接 String a="a"+"b"+"c" 通过编译器优化后,得到的效果是 String a="abc" Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid"; 另一种就是使用new这种标准的构造对象的方法,