buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

Cannot Reference “XxxClass.xxxmember” 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提示错误: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     private 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

 

回到顶部

后记:邂逅OutOfMemoryError

自测时发现,上面代码在某些case下会执行List<T> tList = new ArrayList<>(Integer.MAX_VALUE+1);,由于Integer.MAX_VALUE+1是负数,程序会抛出异常:java.lang.IllegalArgumentException: Illegal Capacity: -2147483648

另外,如果把上面代码行改为List<T> tList = new ArrayList<>(Integer.MAX_VALUE);,则会抛出:java.lang.OutOfMemoryError: Requested array size exceeds VM limit。继续挣扎,试图改为List<T> tList = new ArrayList<>(Integer.MAX_VALUE/2);,亦会抛出:java.lang.OutOfMemoryError: Java heap space

当未指定perBatchCount参数值时,将其默认值指定为Integer.MAX_VALUE实在欠合理!结合使用场景评定后,将上面的阈值PER_BATCH_COUNT_DEFAULT改为99999。

posted on   buguge  阅读(129)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2021-06-15 springboot+rabbitmq 之 消费端配置
点击右上角即可分享
微信分享提示