Java可运行参数评估

Java可运行参数评估,java,runnable,Java,Runnable,我正在用java开发一个客户机服务器,在将自定义可运行实现作为参数从一个对象传递到另一个对象时遇到了问题。 问题是,可运行代码在定义时进行评估(而不是执行),但我希望在调用时对其进行评估。 有什么方法可以实现这种行为吗 下面是受此问题影响的代码: 自定义可运行实现 此处Runnable作为参数传递: 接收对象将ChallengeReportDelegation实例存储为completionOperation,等待超时,然后执行此代码 我想要实现的行为是打印 Leaf Middle a

我正在用java开发一个客户机服务器,在将自定义可运行实现作为参数从一个对象传递到另一个对象时遇到了问题。 问题是,可运行代码在定义时进行评估(而不是执行),但我希望在调用时对其进行评估。 有什么方法可以实现这种行为吗

下面是受此问题影响的代码:

  • 自定义可运行实现
  • 此处Runnable作为参数传递:
  • 接收对象将
    ChallengeReportDelegation
    实例存储为
    completionOperation
    ,等待超时,然后执行此代码
我想要实现的行为是打印

Leaf
Middle
a is: 5
b is: 5
但这就是我得到的

Leaf
Middle
a is: 0
b is: 0

如果你想立即评估某事。我建议根本不要使用runnable。这听起来像是一种apti模式,试图在您只需要值/调用的情况下传递代码


此外,尝试使用可调用或供应商,因为您显然对从子例程返回一些值感兴趣

一个非常简单的例子。让我们用一个字段创建一个runnable

public static void main (String[] args) {
    var x = new Runnable(){
        int a = 0;
        int getA(){
               return a;
        }
        void setA(int v){
            a = v;
        }
        public void run(){
            System.out.println("A : " + getA());
        }
    };
    x.run();
    x.setA(5);
    x.run();
}

第一次是0,第二次是5,因为在调用run时会计算getA。

我找到了一个解决这个问题的有效方法,对于那些来自函数式编程的人来说可能微不足道

根据上次编辑([EDIT2]中的示例)

导入java.util.concurrent.ScheduledThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
导入java.util.function.Consumer;
公开课评价
{
公共静态void main(字符串[]args)引发InterruptedException
{
中间=新中间();
中间。注册(新消费者(){
@凌驾
公共无效接受(值){
System.out.println(“a是:+values.getA());
System.out.println(“b是:+values.getB());
}
});
《睡眠》(2000年);
}
静态类值
{
私有INTA=0;
私有int b=0;
公共int getA(){
返回a;
}
公共无效setA(INTA){
这个a=a;
}
公共int getB(){
返回b;
}
公共休息室(内部b){
这个.b=b;
}
}
静态中产阶级
{
私有ScheduledThreadPoolExecutor池=新ScheduledThreadPoolExecutor(1);
公共无效登记簿(消费者通过)
{
消费者中间消费者=新消费者(){
@凌驾
公共无效接受(值){
System.out.println(“中间”);
通过。接受(值);
}
};
叶子=新叶子(中间消费者);
池。时间表(叶,1,时间单位。秒);
}
}
静态类叶实现可运行
{
公共消费任务;
公共叶(消费者任务)
{
this.task=任务;
}
@凌驾
公开募捐
{
值=新值();
setA(5);
价值观。挫折(5);
System.out.println(“叶”);
接受(价值观);
}
}
}
此代码生成我想要的行为。 希望这能帮助别人。
干杯

你的问题是NPE来自哪里?从这些信息中无法判断。我试图更好地解释。请参阅上次编辑。谢谢,我不知道你的意思。
getXXXChallengeReport()
方法仅在调用
run()
时调用,而不是在声明
Runnable
时调用。可能会显示更完整的代码(不清楚调用了this.challengemanager.recordChallenge()的
this.challengesManager.recordChallenge(),也不清楚它属于哪个类)。您是否已使用断点完成此操作?请提供一个示例来演示此问题,并包括错误的完整堆栈跟踪。您已将一个任务包装在一个任务中。您设置了outter任务的a和b,但原始任务a和b不变。你是故意让这件事复杂化的吗?
public class TestEvaluation
{
    public static void main(String[] args) throws InterruptedException
    {
        Middle middle = new Middle();

        middle.register(new Task() {
            @Override
            public void run() {
                System.out.println("a is: " +  getA());
                System.out.println("b is: " +  getB());
            }
        });

        Thread.sleep(2000);
    }

    abstract static class Task implements Runnable
    {
        private int a = 0;
        private int b = 0;

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        public int getB() {
            return b;
        }

        public void setB(int b) {
            this.b = b;
        }

        @Override
        abstract public void run();
    }

    static class Middle
    {
        private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);

        public void register(Task task)
        {
            Leaf leaf = new Leaf(new Task() {
                @Override
                public void run() {
                    System.out.println("Middle");
                    task.run();
                }
            });
            pool.schedule(leaf, 1, TimeUnit.SECONDS);
        }
    }

    static class Leaf implements Runnable
    {
        public Task task;

        public Leaf(Task task)
        {
            this.task = task;
        }

        @Override
        public void run()
        {
            task.setA(5);
            task.setB(5);
            System.out.println("Leaf");
            task.run();
        }
    }
}
Leaf
Middle
a is: 5
b is: 5
Leaf
Middle
a is: 0
b is: 0
public static void main (String[] args) {
    var x = new Runnable(){
        int a = 0;
        int getA(){
               return a;
        }
        void setA(int v){
            a = v;
        }
        public void run(){
            System.out.println("A : " + getA());
        }
    };
    x.run();
    x.setA(5);
    x.run();
}
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class TestEvaluation
{
    public static void main(String[] args) throws InterruptedException
    {
        Middle middle = new Middle();

        middle.register(new Consumer<Values>() {
            @Override
            public void accept(Values values) {
                System.out.println("a is: " +  values.getA());
                System.out.println("b is: " +  values.getB());
            }
        });

        Thread.sleep(2000);
    }

    static class Values
    {
        private int a = 0;
        private int b = 0;

        public int getA() {
            return a;
        }

        public void setA(int a) {
            this.a = a;
        }

        public int getB() {
            return b;
        }

        public void setB(int b) {
            this.b = b;
        }
    }

    static class Middle
    {
        private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1);

        public void register(Consumer<Values> passed)
        {
            Consumer<Values> middleConsumer = new Consumer<Values>() {
                @Override
                public void accept(Values values) {
                    System.out.println("Middle");
                    passed.accept(values);
                }
            };

            Leaf leaf = new Leaf(middleConsumer);
            pool.schedule(leaf, 1, TimeUnit.SECONDS);
        }
    }

    static class Leaf implements Runnable
    {
        public Consumer<Values> task;

        public Leaf(Consumer<Values> task)
        {
            this.task = task;
        }

        @Override
        public void run()
        {
            Values values = new Values();
            values.setA(5);
            values.setB(5);
            System.out.println("Leaf");
            task.accept(values);
        }
    }
}