Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 传递匿名类_Java_Interface_Anonymous - Fatal编程技术网

Java 传递匿名类

Java 传递匿名类,java,interface,anonymous,Java,Interface,Anonymous,这是Java的一个问题。我有一个名为IMyObjectPredicate的接口,它实现了一个应用于输入的测试方法: 公共接口IMyObjectPredicate{ 布尔测试(myobjectx); } 我希望能够在对象之间传递IMyObjectPredicate的实例,并让test函数将其对变量的引用更新为它所传递到的新对象的引用。例如,考虑使用谓词的类: 公共类测试器{ 对象o; IMyObjectPredicate myTestFunction; int myThreshold; 公共测试

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

公共接口IMyObjectPredicate{
布尔测试(myobjectx);
}
我希望能够在对象之间传递
IMyObjectPredicate
的实例,并让
test
函数将其对变量的引用更新为它所传递到的新对象的引用。例如,考虑使用谓词的类:

公共类测试器{
对象o;
IMyObjectPredicate myTestFunction;
int myThreshold;
公共测试人员(/*stuff*/){
/*此处的代码初始化Tester实例和“myThreshold”*/
myTestFunction=新的IMyObjectPredicate(){
@凌驾
公共布尔测试(MyObject o){
返回(o.value()>myThreshold);
}
};
}
公共布尔值是好的(){
返回myTestFunction.test(o);
}
}
我希望能够执行Tester对象的深度克隆,原因我将在这里不赘述。但是想法是,
Tester
的克隆实例应该根据自己的
myThreshold
值测试谓词,而不是引用第一个实例的
myThreshold
。但是如果我将
myTestFunction
传递给
Tester
的一个新实例,我猜它仍然会引用第一个实例的
myThreshold
值,而不是基于封闭类的引用动态评估
myThreshold

如何完成
IMyObjectPredicate
对象的传递,该对象的测试函数使用对其传递到的新对象字段的引用

编辑:
一个复杂的因素是,一般来说,不可能仅从
Tester
对象中的字段重构
myTestFunction
myTestFunction
可能被程序的其他部分以与
Tester
的其他字段不相关的方式覆盖。如果需要的话,我可以牺牲这个功能,但我宁愿不要为了优雅。

Java没有API来代替匿名类的封闭上下文

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

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

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

class PredicateFactory {
    IMyObjectPredicate thresholdPredicate(int threshold) {
        return new IMyObjectPredicate {
              //...
        }
    }
}
然后您可以将这个工厂赋给对象,该对象将使用它自己的阈值来构造谓词的新实例

factory.thresholdPredicate(myThreshold);

Java没有API来替换匿名类的封闭上下文

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

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

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

class PredicateFactory {
    IMyObjectPredicate thresholdPredicate(int threshold) {
        return new IMyObjectPredicate {
              //...
        }
    }
}
然后您可以将这个工厂赋给对象,该对象将使用它自己的阈值来构造谓词的新实例

factory.thresholdPredicate(myThreshold);

如果
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);
    }
}
公共IMyObjectPredicate{
私有整数阈值;
私有谓词pred;
public int getThreshold(){
返回阈值;
}
公共谓词getPredicate(){
返回pred;
}
公共IMObject谓词(int阈值,谓词pred){
这个阈值=阈值;
this.pred=pred;
}
公共布尔测试(MyObject o){
返回预测试(o);
}
}
公共类测试员{
对象o;
IMyObjectPredicate myTestFunction;
IMyObjectPredicate myTestFunctionCopyWithDiffThreshold;
int myThreshold;
公共测试人员(/*stuff*/){
/*此处的代码初始化Tester实例和“myThreshold”*/
myTestFunction=
新的IMyObjectPredicate(myThreshold,o->o.value()>getThreshold());
myTestFunctionCopyWithDiffThreshold=
新的ImObjectPredicate(5,myTestFunction.getPredicate());
}
公共布尔值是好的(){
返回myTestFunction.test(o);
}
}

这是最合理的解决方案,因为
ImObjectPredicate
应该存储自己的阈值,如果该值唯一地引用了
ImObjectPredicate

,那么如果
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);
    }
}
公共IMyObjectPredicate{
私有整数阈值;
私有谓词pred;
public int getThreshold(){
返回阈值;
}
公共谓词getPredicate(){
返回pred;
}
公共IMObject谓词(int阈值,谓词pred){
这个阈值=阈值;
this.pred=pred;
}
公共布尔测试(MyObject o){
返回预测试(o);
}
}
公共类测试员{
对象o;
IMyObjectPredicate myTestFunction;
IMyObjectPredicate myTestFunctionCopyWithDiffThreshold;
int myThreshold;
公共测试人员(/*stuff*/){
/*此处的代码初始化Tester实例和“myThreshold”*/
myTestFunction=
新的IMyObjectPredicate(myThreshold,o->o.value()>getThreshold());
myTestFunctionCopyWithDiffThreshold=
新的ImObjectPredicate(5,myTestFunction.getPredicate());
}
公共布尔值是好的(){
返回myTestFunction.test(o);
}
}
这是最明智的选择