篮之新喜 发表于 2023-6-15 12:09:40

Cannot Reference “XxxClass.xxx” Before Supertype Constructor Has Bee

百度翻译:在调用超类型构造函数之前无法引用“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提示错误:
https://img2023.cnblogs.com/blog/202192/202306/202192-20230615115417119-1894201342.png
 
 

说说我怎么遇到这个问题的?
我有一个组件工具类。
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
https://img2023.cnblogs.com/blog/202192/202306/202192-20230615122230506-923770505.png
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Cannot Reference “XxxClass.xxx” Before Supertype Constructor Has Bee