0

如果我的方法调用是:

obj.getLevelOne().getLevelTwo().getValue();

我想将此方法作为以下参数传递:

boolean checkValue( obj, method , value) 
{
   return obj.method() == value;
}

我想这样调用 checkValue 方法:

checkValue(obj, "getLevelOne().getLevelTwo().getValue", value);

有什么办法可以做到这一点吗?请帮忙。

4

2 回答 2

3

在 Java 中,函数不是一流的概念(但在 Java 8 中出现)。因此,不可能像在许多其他具有函数概念的语言中那样传递方法。

相反,您需要做的是声明一个接口并使用匿名内部类实现它。例如

界面

interface MyGetter {
    Object doGet();
}

检查方法

boolean checkValue(MyGetter getter, Object value) {
    return getter.doGet().equals(value);
}

召唤

checkValue(new MyGetter() {
    public Object doGet() {
        return obj.getLevelOne().getLevelTwo().getValue();
    }
}, 5);

我们在调用中实际做的是创建一个新类和该类型的对象来进行您需要的实际调用。

编辑:

如果您需要不同的返回类型,您可以使接口和检查方法通用,例如

界面

interface MyGetter<T> {
    T doGet();
}

检查方法

<T> boolean checkValue(MyGetter<? extends T> getter, T value) {
    return getter.doGet().equals(value);
}

召唤

checkValue(new MyGetter<SomeClass>() {
    public SomeClass doGet() {
        return obj.getLevelOne().getLevelTwo().getValue();
    }
}, 5); 
于 2012-09-14T10:29:27.423 回答
1

如果你真的想做这样的事情,我建议:

1.使用 Callable 并创建匿名子类。注意:这有点类似于上面给出的“MyGetter”方法,只是它使用了 Callable。不需要我们自己的接口,因为我们可以使用内置于 jdk 中的用于此目的的东西。

public <T> boolean checkValue(Callable<T> valueGetter, T value) {
    return value.equals(valueGetter.call());
}

final MyObject obj = new MyObject();
checkValue(new Callable<String>() { 
     public String call() { return obj.getLevelOne().getLevelTwo().getValue(); }
}, "foo");

2.使用某种 EL 包(mvel 可以很好地用作嵌入式库)。

然后你可以这样做:“levelOne.levelTwo.value”作为你的表达式,并使用 mvel 在“obj”上进行评估。

public <T> boolean checkValue(Object obj, String expression, T value) {
    Object objVal = MVEL.eval(expression, obj);
    return value.equals(objVal);
}
checkValue(obj, "levelOne.levelTwo.value", "foo");

当然,第一个更安全,尽管您的“表达式”将在编译时完成,因为您将其显式编码到可调用实现中。第二种方法更具动态性,可让您在运行时计算表达式。

于 2012-09-14T13:25:14.327 回答