如何重新启动计时器倒计时

发布于 2025-02-04 02:48:05 字数 2154 浏览 1 评论 0 原文

我正在尝试重置计时器,以便它可以从数组中提取另一个值。 有人知道解决方案吗?我的错误是说:

peat = peat= 1; 
local variables referenced from an inner class must be final or effectively final

我被卡住了,我知道我需要重置计时器,但我不知道该计时器。

class MyProgram {

    public static void main(String[] args) {
        int peat = 0;
        int cdown = 0;
        Scanner input1 = new Scanner(System.in);
        System.out.println("What is your name");
        String personsName = input1.next();
        System.out.println((personsName) + " Are you ready to impove yourself");
        String motiv = input1.next();

        String[] myArray = new String[4];
        myArray[0] = "Keep going";
        myArray[1] = "1 more rep";
        myArray[2] = "you have come so far don't stop now";
        myArray[3] = "Think of the progress you have made";

        if (motiv.equals("yes")) {
            System.out.println("Today is the day hard work begins");
        } else {
            System.out.println("type yes when you're ready to work");
        }

        Scanner input2 = new Scanner(System.in);
        System.out.println("You will recive quotes throughout your workout to remind you to keep working type ok if you accept");
        String confirm = input2.next();

        if (confirm.equals("ok")) {
            final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            final Runnable runnable = new Runnable() {
                int countdown = 10;
                public void run() {
                    System.out.println(countdown);
                    countdown--;
                    if (countdown == 0 && peat < 4) {
                        System.out.println(myArray[0]);
                        //reset count down to 10
                        peat = peat + 1;
                    } else {
                        scheduler.shutdown();
                    }
                }
            };
            scheduler.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);
        }
        while (cdown < 1) {
            System.out.println(myArray[1]);
            cdown = cdown + 1;
        }
    }
}

I am trying to reset the timer so it can pull another value from my array.
Does anyone know the solution? My error is saying:

peat = peat= 1; 
local variables referenced from an inner class must be final or effectively final

I am stuck and I know I need to reset the timer but I don't know how.

class MyProgram {

    public static void main(String[] args) {
        int peat = 0;
        int cdown = 0;
        Scanner input1 = new Scanner(System.in);
        System.out.println("What is your name");
        String personsName = input1.next();
        System.out.println((personsName) + " Are you ready to impove yourself");
        String motiv = input1.next();

        String[] myArray = new String[4];
        myArray[0] = "Keep going";
        myArray[1] = "1 more rep";
        myArray[2] = "you have come so far don't stop now";
        myArray[3] = "Think of the progress you have made";

        if (motiv.equals("yes")) {
            System.out.println("Today is the day hard work begins");
        } else {
            System.out.println("type yes when you're ready to work");
        }

        Scanner input2 = new Scanner(System.in);
        System.out.println("You will recive quotes throughout your workout to remind you to keep working type ok if you accept");
        String confirm = input2.next();

        if (confirm.equals("ok")) {
            final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            final Runnable runnable = new Runnable() {
                int countdown = 10;
                public void run() {
                    System.out.println(countdown);
                    countdown--;
                    if (countdown == 0 && peat < 4) {
                        System.out.println(myArray[0]);
                        //reset count down to 10
                        peat = peat + 1;
                    } else {
                        scheduler.shutdown();
                    }
                }
            };
            scheduler.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);
        }
        while (cdown < 1) {
            System.out.println(myArray[1]);
            cdown = cdown + 1;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆梦 2025-02-11 02:48:05

正如错误消息所指出的那样,Java不允许从“ lambda”范围内修改属于外部范围的变量(匿名类的实例也创建了这样的范围)。

就您而言,为了解决此问题,您可以制作 PEAT 类变量:

import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.SECONDS;

public class MyProgram {

    private static int peat = 0;

    public static void main(String[] args) {
        // Code of main()
        // Remove local "peat" variable
    }
}

As the error message states, Java doesn't allow modifying variables belonging to the outer scope from within a "lambda" scope (instances of anonymous classes also create such a scope).

In your case, in order to work-around this issue, you could make peat a class variable:

import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;
import static java.util.concurrent.TimeUnit.SECONDS;

public class MyProgram {

    private static int peat = 0;

    public static void main(String[] args) {
        // Code of main()
        // Remove local "peat" variable
    }
}
鱼窥荷 2025-02-11 02:48:05

这是因为 peat 不是最终或有效的最终变量。如 documentation>

一个匿名类无法访问其封闭范围中未声称为最终或有效最终的局部变量。

当匿名类访问封闭块的本地变量时,匿名类捕获该变量。这意味着该变量的值实际上是在匿名类中复制的。

在您的情况下,您正在使用lambda表达式提供运行的实现。像匿名课程一样,lambda表达式被说,这意味着他们不会引入任何新的范围范围。此外,它们也可以从封闭范围中捕获变量。

就像本地和匿名类一样,lambda表达式可以捕获变量。他们可以同样访问封闭范围的本地变量。 [...] lambda表达式是词汇范围的。这意味着他们不会从超级类型中继承任何名称或引入新的范围。

像本地和匿名类一样,lambda表达式只能访问 final 有效最终

尽管在一个块中声明了一个匿名类,但其上下文与创建的上下文完全分离。必须防止用匿名类进行的任何修改,因为没有办法反映封闭范围中的这些更改。同样,在封闭范围中,该变量必须保持未修改,因为一旦其值被匿名类捕获,封闭范围的任何更改都不能反映到匿名类中。

如果要启动使用 scheduledthreadpoolexecutor 的计时器,则不能依靠在GO上定义的类并使用封闭范围的变量。您需要声明扩展运行的类。在下面的示例中,可以通过传递秒数,对调度程序的引用和一系列消息来实例化计时器类。

class Timer implements Runnable {
    private ScheduledExecutorService scheduler;
    private int numSecs;

    private String[] vetMessages;

    public Timer(ScheduledExecutorService scheduler, int numSecs, String[] vetMessages) {
        this.scheduler = scheduler;
        this.numSecs = numSecs;
        this.vetMessages = vetMessages;
    }

    @Override
    public void run() {
        numSecs--;
        if (numSecs < 4) {
            System.out.println(vetMessages[numSecs]);
            if (numSecs <= 0) {
                scheduler.shutdown();
            }
        }
    }
}

class MyProgram {

    public static void main(String[] args) {
        Scanner input1 = new Scanner(System.in);
        System.out.println("What is your name");
        String personsName = input1.next();
        System.out.println((personsName) + " Are you ready to impove yourself");
        String motiv = input1.next();

        String[] myArray = new String[4];
        myArray[0] = "Keep going";
        myArray[1] = "1 more rep";
        myArray[2] = "you have come so far don't stop now";
        myArray[3] = "Think of the progress you have made";

        if (motiv.equals("yes")) {
            System.out.println("Today is the day hard work begins");
        } else {
            System.out.println("type yes when you're ready to work");
        }

        Scanner input2 = new Scanner(System.in);
        System.out.println("You will recive quotes throughout your workout to remind you to keep working type ok if you accept");
        String confirm = input2.next();

        if (confirm.equals("ok")) {
            final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            Timer t = new Timer(scheduler, 10, myArray);

            //Added an initial delay of 1 second to not start the Timer immediately and decrement the number of seconds right away
            scheduler.scheduleAtFixedRate(t, 1, 1, TimeUnit.SECONDS);
        }
    }
}

This is because peat is not a final or an effectively-final variable. As the documentation states:

An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

When an anonymous class accesses a local variable of the enclosing block, the anonymous class captures that variable. Meaning that the variable's value is literally copied within the anonymous class.

In your case, you're using a lambda expression to provide an implementation of Runnable. Like anonymous classes, lambda expressions are said lexically scoped, meaning that they do not introduce any new level of scoping. Furthermore, they can too capture variables from the enclosing scope.

Like local and anonymous classes, lambda expressions can capture variables; they have the same access to local variables of the enclosing scope. [...] Lambda expressions are lexically scoped. This means that they do not inherit any names from a supertype or introduce a new level of scoping.

like local and anonymous classes, a lambda expression can only access local variables and parameters of the enclosing block that are final or effectively final.

Although an anonymous class is declared within a block, its context is completely dissociated from the one where it has been created. Any modification made from the anonymous class must be prevented, as there is no way to reflect those changes in the enclosing scope. Likewise, in the enclosing scope, the variable must remain unmodified, as once its value has been captured by the anonymous class, any changes from the enclosing scope cannot be reflected into the anonymous class.

If you want to launch a timer with a ScheduledThreadPoolExecutor, then you cannot rely on a class defined on the go and use the enclosing scope's variables. You need to declare a class extending Runnable. In the following example, the Timer class can be instantiated by passing the number of seconds, a reference to the scheduler and an array of messages.

class Timer implements Runnable {
    private ScheduledExecutorService scheduler;
    private int numSecs;

    private String[] vetMessages;

    public Timer(ScheduledExecutorService scheduler, int numSecs, String[] vetMessages) {
        this.scheduler = scheduler;
        this.numSecs = numSecs;
        this.vetMessages = vetMessages;
    }

    @Override
    public void run() {
        numSecs--;
        if (numSecs < 4) {
            System.out.println(vetMessages[numSecs]);
            if (numSecs <= 0) {
                scheduler.shutdown();
            }
        }
    }
}

class MyProgram {

    public static void main(String[] args) {
        Scanner input1 = new Scanner(System.in);
        System.out.println("What is your name");
        String personsName = input1.next();
        System.out.println((personsName) + " Are you ready to impove yourself");
        String motiv = input1.next();

        String[] myArray = new String[4];
        myArray[0] = "Keep going";
        myArray[1] = "1 more rep";
        myArray[2] = "you have come so far don't stop now";
        myArray[3] = "Think of the progress you have made";

        if (motiv.equals("yes")) {
            System.out.println("Today is the day hard work begins");
        } else {
            System.out.println("type yes when you're ready to work");
        }

        Scanner input2 = new Scanner(System.in);
        System.out.println("You will recive quotes throughout your workout to remind you to keep working type ok if you accept");
        String confirm = input2.next();

        if (confirm.equals("ok")) {
            final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            Timer t = new Timer(scheduler, 10, myArray);

            //Added an initial delay of 1 second to not start the Timer immediately and decrement the number of seconds right away
            scheduler.scheduleAtFixedRate(t, 1, 1, TimeUnit.SECONDS);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文