传递匿名类

时间:2016-07-26 16:45:05

标签: java interface anonymous

这是Java的问题。我有一个名为IMyObjectPredicate的接口,它实现了一个应用于输入的测试方法:

public interface IMyObjectPredicate {
    boolean test(MyObject x);
}

我想要的是能够在对象之间传递IMyObjectPredicate的实例,并让test函数将其对变量的引用更新为传递给它的新对象的引用。例如,考虑一个使用此谓词的类:

public class Tester {
    MyObject o;
    IMyObjectPredicate myTestFunction;
    int myThreshold;

    public Tester(/*stuff*/) {
        /*Code here which initialises the Tester instance and 'myThreshold'*/
        myTestFunction = new IMyObjectPredicate() {
            @Override
            public boolean test(MyObject o) {
                return (o.value() > myThreshold);
            }
        };
    }

    public boolean isGood() {
        return myTestFunction.test(o);
    }
}

我希望能够执行Tester对象的深度克隆,原因我不会进入此处。但我们的想法是,Tester的克隆实例应该根据{em>自己的值myThreshold来测试谓词,而不是引用第一个实例的myThreshold。但是,如果我将myTestFunction传递给Tester的新实例,我猜它仍然会引用第一个实例的myThreshold值,而不是基于myThreshold动态评估IMyObjectPredicate封闭类的参考。

如何完成myTestFunction对象的传递,该对象的测试函数使用对传递给的新对象的字段的引用?

修改 一个复杂的因素是,通常,不可能仅从Tester对象中的字段重建myTestFunctionTester可能会以与WHERE EI.ATTENDED = Attended and BEI.ATTENDED = Attended 的其他字段无关的方式被程序的其他部分覆盖。如果需要,我可以牺牲这个功能,但我宁愿不为了优雅。

2 个答案:

答案 0 :(得分:2)

Java没有用于替换匿名类的封闭上下文的API。

我从简化示例中可以看到的最简单的解决方案是为测试函数的签名添加阈值。据我所知,无论如何都会出现门槛。

public interface IMyObjectPredicate {
    boolean test(MyObject x, int threshold);
}

另一种方法是使用一些工厂方法,它将为提供的阈值创建一个谓词,如

class PredicateFactory {
    IMyObjectPredicate thresholdPredicate(int threshold) {
        return new IMyObjectPredicate {
              //...
        }
    }
}

然后你可以将这个工厂传递给对象,该对象将使用它自己的阈值来构造谓词的新实例

factory.thresholdPredicate(myThreshold);

答案 1 :(得分:0)

如果ImObjectPredicate是一个只存储对谓词而不是接口的引用的类,则会容易得多。如果您能够进行更改,则每个谓词都可以存储自己的阈值,从而解决问题。

public IMyObjectPredicate {
    private int threshold;
    private Predicate<MyObject> pred;

    public int getThreshold() {
        return threshold;
    }

    public Predicate<MyObject> getPredicate() {
        return pred;
    }

    public IMObjectPredicate(int threshold, Predicate<MyObject> pred) {
        this.threshold = threshold;
        this.pred = pred;
    }

    public boolean test(MyObject o) {
        return pred.test(o);
    }
}

public class Tester {
    MyObject o;
    IMyObjectPredicate myTestFunction;
    IMyObjectPredicate myTestFunctionCopyWithDiffThreshold;
    int myThreshold;

    public Tester(/*stuff*/) {
        /*Code here which initialises the Tester instance and 'myThreshold'*/
        myTestFunction =
            new IMyObjectPredicate(myThreshold, o -> o.value() > getThreshold());
        myTestFunctionCopyWithDiffThreshold =
            new ImObjectPredicate(5, myTestFunction.getPredicate());
    }

    public boolean isGood() {
        return myTestFunction.test(o);
    }
}

这是最明智的解决方案,因为ImObjectPredicate 存储自己的阈值,如果该值唯一引用ImObjectPredicate