将多级对象方法作为参数传递

时间:2012-09-14 10:19:39

标签: java

如果我的方法调用是:

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

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

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

我想像这样调用checkValue方法:

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

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

2 个答案:

答案 0 :(得分:3)

在java中函数不是第一类概念(但是,在Java 8中)。因此,不可能在许多其他具有功能概念的语言中传递方法。

您需要做的是声明一个接口并使用匿名内部类来实现它。 e.g。

界面

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); 

答案 1 :(得分: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");

当然,第一个类型更安全,虽然你的“表达式”将在编译时完成,因为你明确地将它编码到可调用的实现中。第二种方法更具动态性,允许您在运行时计算表达式。