iT邦幫忙

0

java: 創建完TimerTask為何可以直接寫大括號{ } ?

  • 分享至 

  • xImage
  1. 為何TimerTask task = new TimerTask(){...}可直接加{}並寫入執行過程呢? 是任何物件在創建後皆可以直接加{}嗎?
  2. 若將int count寫在Main()中會出錯 "Local variable count defined in an enclosing scope must be final or effectively final",將int test寫在Main()卻不會出錯,這是為何呢?
public class Main{
	Main(){
		int count = 3;
        int test = 15;
		Timer timer = new Timer();
		TimerTask task = new TimerTask() {
			@Override
			public void run() {
				if(count>0) {
					System.out.println(count);
					count--; // Local variable count defined in an enclosing scope must be final or effectively final
                    System.out.println(test);// 不會出錯
				}else {
					timer.cancel();
				}
			}
		};
		timer.schedule(task, 0,1000);
	}
	public static void main(String[] args){
		new Main();
	}
}
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

4
galaxian85
iT邦新手 4 級 ‧ 2022-02-11 12:41:06
  1. 那叫做匿名內部類別, TimerTask 是一個抽象類別, 匿名內部類別方便我們直接在原本的程式內撰寫邏輯, 而不用開一個新的 class extends TimerTask
  2. 這是 Java 的規範, 匿名內部類別可以使用外部的變數, 但是不可以更改變數的值 (就是錯誤訊息裡面 must be final or effectively final 的意思). 如果真的想要實現這種邏輯, 可以寫一個簡單的物件來達成你想要的功能
class Counter {
    private int value;
    
    public Counter(int i) {
        value = i;
    }
    
    public int getValue() {
        return value;
    }
    
    public void setValue(int i) {
        value = i;
    }
}
看更多先前的回應...收起先前的回應...
crazy iT邦新手 5 級 ‧ 2022-02-13 11:58:54 檢舉

非常感謝

crazy iT邦新手 5 級 ‧ 2022-02-13 15:37:18 檢舉

galaxian85
非常感謝您,想請問那為什麼把int count = 3;拿到Main()建構子外就不會出錯了呢,它也符合在匿名內部類別的"外部"呀?

你原本的 count 是 Main() 這個建構子的區域變數, 往外面放 count 就變成 class Main 的成員變數了, 不好意思是我沒有講清楚, "must be final or effectively final" 這個規則只適用於區域變數

crazy iT邦新手 5 級 ‧ 2022-02-13 20:20:24 檢舉

了解了 謝謝您

1
Cyril
iT邦新手 5 級 ‧ 2022-02-12 19:55:56
  1. 是任何物件在創建後皆可以直接加{}嗎?
    沒有標示 final 的 class 都可以加, 像 Integer/String 這種被標示成 final 的 class 就沒辦法
        Timer timer = new Timer() {
            @Override
            public void schedule(TimerTask task, long delay) {
                super.schedule(task, delay);
                System.out.println("schedule be performed");
            }
        };

我要發表回答

立即登入回答