Groovy中带参数的java创建方法dynamicali
我有一个要求,例如,我使用SuperCSV读取csv文件并映射到对象
SuperCSV有一个要求,如果标头指定字段名“firstName”,则需要在类中包含setFirstName()方法,否则会引发异常
现在如果我使用groovybeans,那么我不需要声明所有这些方法,只要声明变量就可以了
但我在寻找一个更动态的解决方案,我们甚至不必声明这些变量
例如,只要动态创建一个对象,并且使用groovy的动态方法创建特性,SuperCSV就能够找到setter
我查看了各种选项,如Expando、ExpandoMetaClass,但这些都不符合我的目的
任何答复都将不胜感激
以下是对我有用的代码片段,它对减少大量代码和不必要的逻辑非常有帮助:
static def testBeanReader()
{
ICsvBeanReader beanReader = null;
try
{
beanReader = new CsvBeanReader(new FileReader("src/test.csv"),
CsvPreference.STANDARD_PREFERENCE);
}
catch(Exception e)
{
}
final String[] header = VirtualObject.getHeaders();
final CellProcessor[] processors = VirtualObject.getProcessors();
//Class c1 = createNewClass()
//String s = createClass()
def list = ["name", "age"]
def c = (new GroovyShell().evaluate(createClass(list)) as Class)
//println(c.methods.grep {it.name.startsWith("get")})
GroovyObject groovyObject = (GroovyObject)(beanReader.read(c, header, processors))
Object[] args = {};
println(groovyObject.getProperty("name"))
}
static def createClass(def list)
{
String classDeclaration = "\nclass Test {\n"
list.each
{
classDeclaration+="def $it\n"
}
classDeclaration+= """
}
return Test.class
"""
return classDeclaration
}
这适用于supercsv,但可以用于一般java对象,只需对语法进行少量更改
# 1 楼答案
您不能使用GroovyShell动态地构造这些类吗
这是不安全的,但它会动态创建与Java兼容的类
我不熟悉SuperCSV,但我认为当Expando或元类解决方案使用Groovy元对象协议时,它应该使用类似smth的反射
GroovyShell(或GroovyClassLoader)将能够创建正常的类,并具有工作反射
编辑:说明生成类的动态性质。我们首先创建类源代码(根据我们的需要,从运行时信息,从您的CSV头创建),然后使用它