在調用超類型構造函數之前無法引用“XxxClass.xxx” -----在一個類的構造器方法還未執行的時候,我們無法使用這個類的成員屬性或成員方法。 ...
百度翻譯:在調用超類型構造函數之前無法引用“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提示錯誤:Cannot reference 'MyException.getErrorCode' before supertype constructor has been called
.
說說我怎麼遇到這個問題的?
我有一個組件工具類。
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
當看到一些不好的代碼時,會發現我還算優秀;當看到優秀的代碼時,也才意識到持續學習的重要!--buguge
本文來自博客園,轉載請註明原文鏈接:https://www.cnblogs.com/buguge/p/17482556.html