为方法调用赋值

时间:2013-08-02 01:01:07

标签: java methods hashmap invoke getter

供以后参考:

Operations o = new Operations(); //class containing the operation methods
HashMap<String, Method> ops = new HashMap<String, Method>();

我正在开发一个程序,它将通过控制台解析数学表达式输入,或者最终可能是GUI。

目前,我有一个名为“Operations”的类,它有各种基本的数学函数(稍后将添加更多,现在只测试)。在另一个类中,我有一个方法,通过获取操作数,连续运算符和另一个操作数来计算结果,并调用一个方法来计算表达式。它将计算所需的信息存储在:

double numOne = //...
char operator = //...
double numTwo = //...
double result = //...

现在我不希望发表长switch / case声明或if声明:

if (operator.equals("+")) //I know .equals() doesn't use chars; it's an example
     o.add(numOne, numTwo);
else if (operator.equals("-"))
     o.subtract(numOne, numTwo);

每次操作都会打开。这就是为什么我尝试创建一个HashMap<String, Method>来存储运算符(String)和应该调用的方法。基本上,在当前类的构造函数中,我把:

ops.put("+", o.getClass().getMethod("add", double.class, double.class));
ops.put("-", o.getClass().getMethod("subtract", double.class, double.class));
//etc. Which in and of itself is also pretty lengthy

现在,一旦通过运算符识别方法,我需要另一种方法来返回Method来调用。

private Method getMethodFromKey(HashMap<String, Method> map, char op) {
    Method method = null;
    for (Map.Entry<String, Method> e: map.entrySet()) {
        if (e.getKey().equals(op))
            method = e.getValue();
    }
    return method;
}

最后,一旦我有正确的方法,我可以用:

来调用它
getMethodFromKey(ops, operator).invoke(o, numOne, numTwo);

一切都很好。我的问题是,我/将要调用的方法是getter方法;他们返回双倍。例如:

public double add(double one, double two) {
    double answer = 0;
    answer = one + two;
    return answer;
}

我想这只是一个冗长的问题,是否有办法分配一个innvoked方法的返回值?类似的东西:

result = getMethodFromKey(ops, operator).invoke(o, numOne, numTwo); //This doesn't work :(

感谢任何帮助。另外,如果我的方法完全错误,我会欣赏正确的方向。


免责声明:我对Java相对缺乏经验并因过于复杂的事情而闻名,所以请指出我的设计中存在的任何严重缺陷。 :)

3 个答案:

答案 0 :(得分:1)

如果invoke()返回Object您知道的double,则可以这样投出:

result = (Double) getMethodFromKey(ops, operator).invoke(o, numOne, numTwo); 

由于double是基元,而不是Object类型,因此您需要将其转换为Double,并通过unboxing,我们得到double 1}}。

答案 1 :(得分:1)

如果您确定所有操作都将在一个类上(无可扩展性),那么您应该考虑使用enum。您可以add an instance fieldenum来表示与操作对应的字符命令,然后使用由evaluate值实现的抽象enum方法。

答案 2 :(得分:1)

invoke()返回Object,由于Java不知道如何将Object分配给double,因此无法编译。 invoke首先将方法中的double装入Double。您现在必须从Object转换为Double(然后可以调用.doubleValue(),但这会自动完成)以使其生效。

  

我因为过于复杂的事情而闻名,所以请指出我的设计中存在的任何严重缺陷。 :)

使用反射而不是界面。 Method是一个函数对象。但它使用起来并不安全。没有这些问题,接口也可以这样做。

interface Operation {
    double evaluate(double a, double b);
}

然后在地图中放置实现接口的对象:

ops.put("+", new Operation() {
    public double evaluate(double a, double b) {
        return a+b;
    });

你可以做到

double result = getMethodFromKey(ops, operator).evaluate(numOne, numTwo);

投射的需要消失了。