Cannot Reference “XxxClass.xxx” Before Supertype Constructor Has Been Called

百度翻譯:在調用超類型構造函數之前無法引用“XxxClass.xxx” ----- 我的理解:一個類的構造器方法還未執行的時候,我們無法使用類的成員屬性或成員方法。

 

下面是此錯誤的示例代碼

public class MyException extends RuntimeException {
    private int errorCode = 0;
    
    public MyException(String message) {
        super(message + getErrorCode()); // compilation error
    }

    public int getErrorCode() {
        return errorCode;
    }
}

IDE提示錯誤:

 

 


說說我怎麼遇到這個問題的?

我有一個組件工具類。

 1 @Slf4j
 2 public class Many2OneProcessor<T> {
 3 
 4     private static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(15);
 5 
 6     /**
 7      * 將多長時間的多次操作合併成1次,單位:秒
 8      */
 9     private final long intervalSecond;
10     /**
11      * 每次處理多少條數據
12      */
13     private final int perBatchCount;
14     /**
15      * 批次處理邏輯代碼
16      */
17     private final Consumer<List<T>> yourBusinessCode;
18     private final ...
19 
20     public Many2OneProcessor(long intervalSecond, Class<T> tClass, Consumer<List<T>> yourBusinessCode) {
21         this(intervalSecond, Integer.MAX_VALUE, tClass, yourBusinessCode);
22     }
23 
24     public Many2OneProcessor(long intervalSecond, int perBatchCount, Class<T> tClass, Consumer<List<T>> yourBusinessCode) {
25         
26         ...此處省略若干行
27         
28     }    
29     
30     public void produce(T t) {
31         redisUtil.lSet(LIST_KEY, t, HOURS.toMillis(1));
32         scheduledThreadPool.schedule(this::consumeMsg, intervalSecond, TimeUnit.SECONDS);
33     }
34 
35     public void consumeMsg() {
36         redisLockTemplate.execute(LOCK_KEY, TimeUnit.SECONDS.toMillis(intervalSecond - 1), false, () -> {
37             
38             ...
39             
40             List<T> tList = new ArrayList<>(perBatchCount + 1);
41             for (int j = 0; j < perBatchCount; j++) {
42                 Object o = redisUtil.lPop(LIST_KEY);
43                 if (o == null) break;
44                 tList.add((T) o);
45             }
46             if (perBatchCount != Integer.MAX_VALUE && redisUtil.lGetListSize(LIST_KEY) > 0) {
47                 scheduledThreadPool.schedule(this::consumeMsg, intervalSecond, TimeUnit.SECONDS);
48             }
49             
50             ...
51             yourBusinessCode.accept(tList);
52             
53         });
54     }
55 }

 

注意到其中的兩處Integer.MAX_VALUE。這無形中提高了代碼理解和維護(重點是前者)的成本。

於是,做點重構。改爲下面這樣,代碼的可理解方面,更上一層樓。

public class Many2OneProcessor<T> {
    /**
     * 每次處理多少條數據
     */
    private final int perBatchCount;
    private static final int PER_BATCH_COUNT_DEFAULT = Integer.MAX_VALUE;
    
    public Many2OneProcessor(long intervalSecond, Class<T> tClass, Consumer<List<T>> yourBusinessCode) {
        this(intervalSecond, PER_BATCH_COUNT_DEFAULT, tClass, yourBusinessCode);
    }
    
    public void consumeMsg() {
        ...
        
            if (perBatchCount != PER_BATCH_COUNT_DEFAULT && redisUtil.lGetListSize(LIST_KEY) > 0) {
        ...
    }
}

 

注意,PER_BATCH_COUNT_DEFAULT 需要定義爲static。否則會出現上面的預編譯錯誤。Cannot reference 'Many2OneProcessor.PER_BATCH_COUNT_DEFAULT' before supertype constructor has been called。另外,在重構過程中,我使用了一種方案,見下圖,也出現了這個錯誤:Cannot reference 'Many2OneProcessor.perBatchCount' before supertype constructor has been called

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章