从字符串构造实例并使用它们的类型返回它们的方法?

时间:2013-01-12 22:11:04

标签: java

给定两个类AB具有单参数构造函数和二元函数f,我需要解析形式的字符串

"f(A(10), B(20))"
"f(A(2), A(3))"

创建适当的实例并调用相应的函数:

class Functions {
    public static double f(A a1, A a2);
    public static double f(A a, B b);
    public static double f(B b1, B b2);
    // ...
}

所以我要找的是一种类型的方法

T createInstanceFromString(String desc);

从“A(10)”或“B(20)”等字符串创建实例。当然,不幸的是,这在Java中是不可能的。

非常感谢任何有关此问题解决方案的建议。

编辑:我忘了提及可能存在大量不同的类ABC等等函数fg等。我想使用createInstanceFromString将解析与调用分开,否则必须为每个函数调用分别有条件地解析,这会带来很多代码重复。

Edit2 :问题不是关于如何解析,而是关于如何解析然后以通用方法/工厂/其他方式返回实例。

3 个答案:

答案 0 :(得分:2)

您需要对String进行标记。 (如果它始终以f(开头,以)结尾,则可以让您的生活更轻松,删除这些部分。)

A(4) - >找到类名 - > A - >找到参数 - > 4

这样做(伪java代码):

public static Object createClass(String className, Double value){
    Class a = Class.forName(className);
    Class[] params = new Class[]{Integer.class};
    Constructor c = a.getConstructor(params);
    Object[] values = new Object[]{value};
    return c.newInstance();
}

也许,这个很有用:http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

<强>更新 这就像编写一个编译器。如果您阅读了有关如何编写编译器的内容,可以获得更多信息:http://en.wikipedia.org/wiki/Compiler

更新2 将所有生成的实例放入数组中。现在,您可以使用reflection-API获取正确的方法f。守则将类似于

http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getDeclaredMethod(java.lang.String,java.lang.Class ...)

Object[] values ...
Class[] classes ...
for(Object o: values){
    add o.getClass() to classes
}

Method f = Functions.getClass().getDeclaredMethods("f", classes);
f.invoke(values);

答案 1 :(得分:0)

我认为你应该为每个函数创建一个类,并调用像“compute”这样的静态方法。 这样,您就可以从String解析类名和属性,并通过类加载器加载适当的类。您可以通过一个或多个HashMap变量传递可变数量的参数,其中包含名称作为键,变量作为值。

答案 2 :(得分:0)

我还没试过,但看起来你可以通过

来上课
Class clazz = Class.forName("NameOfTheWantedClass");

而不是

Constructor[] constructors = clazz.getConstructors();

然后使用

搜索想要的构造函数
getParameterTypes() 

在每个构造函数上并选择想要的构造函数。

但我建议考虑改变你的方法,Class.forName("NameOfTheWantedClass")reflection的使用总是有一种不好的做法。并且只应在真正必要时使用。