在调用超类型构造函数之前无法引用“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
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!-