2

给定两个类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 中是不可能的。

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

编辑:我忘了提到可能有大量不同的类A、、BC以及大量的函数fg等等。我想用它createInstanceFromString来将解析与调用分开,否则必须有条件地单独解析对于每个函数调用,都会带来大量的代码重复。

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

4

3 回答 3

2

您需要对字符串进行标记。(如果它总是以您开头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 将所有生成的实例放入一个数组中。现在您可以使用反射 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);
于 2013-01-12T22:34:13.140 回答
0

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

于 2013-01-12T22:18:07.527 回答
0

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

Class clazz = Class.forName("NameOfTheWantedClass");

然后

Constructor[] constructors = clazz.getConstructors();

而不是通过使用搜索想要的构造函数

getParameterTypes() 

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

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

于 2013-01-12T22:22:26.617 回答