我需要帮助理解java中的Timer类的scheduleAtFixedRate方法

作为番茄钟技术的粉丝,我正在制作一个倒数计时器让我完成我的作业任务。 然而,这个特殊的项目不是功课。 🙂

Stack有很多关于在用户输入之前使用定时器来控制延迟的问题,但在独立的定时器上并不是很多。 我从朋友那里遇到过这段代码,并且已经在Java Documentation上学过这门课程。

public class Stopwatch { static int interval; static Timer timer; public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Input seconds => : "); String secs = sc.nextLine(); int delay = 1000; int period = 1000; timer = new Timer(); interval = Integer.parseInt( secs ); System.out.println(secs); timer.scheduleAtFixedRate(new TimerTask() { public void run() { System.out.println(setInterval()); } }, delay, period); } private static final int setInterval() { if( interval== 1) timer.cancel(); return --interval; } } 

有些语法对我来说并不清楚。 考虑:

 timer.scheduleAtFixedRate(new TimerTask() { public void run() { System.out.println(setInterval()); } }, delay, period); 

我不明白括号和括号是如何工作的。 乍一看,考虑到scheduleAtFixedRate(TimerTask task, long delay, long period)我可以看到delayperiod参数,但不能看到第一个参数之前的开放状态。

我的第一个参数实际上是整个代码块吗? 我希望整个区块被圆括号包围……但事实并非如此。 这是java中的常见语法吗? 我以前从未碰过它。

new TimerTask(){public void run(){System.out.println(setInterval()); }}

我只是想澄清一下,在我开始改变之前我理解它。

 timer.scheduleAtFixedRate(new TimerTask() { public void run() { System.out.println(setInterval()); } }, delay, period); 

该代码等同于此重构,其中new TimerTask被分配给局部变量。

 TimerTask task = new TimerTask() { public void run() { System.out.println(setInterval()); } }; timer.scheduleAtFixedRate(task, delay, period); 

当然,奇怪的部分刚刚向上移动了一点。 什么是这个new TimerTask东西,究竟是什么?

Java具有用于定义匿名内部类的特殊语法。 匿名类是语法上的便利。 您可以在使用点定义它及其run()方法,而不是在别处定义TimerTask的子类。

上面的代码等同于以下代码,匿名的TimerTask子类变成了一个显式命名的子类。

 class MyTimerTask extends TimerTask { public void run() { System.out.println(setInterval()); } } TimerTask task = new MyTimerTask(); timer.scheduleAtFixedRate(task, delay, period); 

你是对的,第一个参数是整个代码块:

 new TimerTask() { public void run() { System.out.println(setInterval()); } } 

这些声明称为匿名类,并在Java教程中有更详细的解释。

这是一个匿名的内部阶级 。 你需要学习内部类来理解这一点 。 通常,当您不需要在代码中的其他位置使用类时,将使用此类。 你不能在其他地方使用它只是因为你没有指向它的引用。 您也可以按如下方式替换上面的代码:

 class MyTimerTask extends TimerTask { @Override public void run() { // Timer task code goes here. System.out.println(setInterval()); } } MyTimerTask timerTask = new MyTimerTask(); timer.scheduleAtFixedRate(timerTask, delay, period);