用匿名内部类优雅地计算方法执行时间

一、从一个 "笨办法" 说起

前几天在写一个数据处理模块时,突然想测一下某个方法的耗时。第一反应是这样的:

java 复制代码
public void doSomething() {
    long start = System.currentTimeMillis();
    // ... 业务逻辑
    long end = System.currentTimeMillis();
    System.out.println("耗时: " + (end - start) + "ms");
}

写了几遍之后就开始烦躁了 ------每个方法都要复制粘贴这三行代码,而且一旦不需要测速了,还得一个个删掉,代码变得又脏又乱。

有没有一种更优雅的方式,既能计算方法耗时,又不污染业务代码?

二、思路:把 "测速" 抽象成一个模板

仔细一想,这其实是一个经典的模板方法模式场景:

记录开始时间

执行某个方法(这是变化的)

记录结束时间并输出

变化的只有第 2 步,那能不能把这部分 "抽出来" 呢?

三、匿名内部类登场

定义一个抽象类,把不变的骨架写好,把变化的部分留给子类:

java 复制代码
public abstract class TimeCalculator {
    
    public final void calculate() {
        long start = System.currentTimeMillis();
        
        // 变化的部分,交给子类实现
        doWork();
        
        long end = System.currentTimeMillis();
        System.out.println("方法执行耗时: " + (end - start) + "ms");
    }
    
    // 抽象方法,由子类实现具体业务
    public abstract void doWork();
}

然后在使用时,匿名内部类就派上用场了:

java 复制代码
public class Demo {
    public static void main(String[] args) {
        // 匿名内部类,现场实现 doWork()
        new TimeCalculator() {
            @Override
            public void doWork() {
                // 这里写你的业务代码
                try {
                    Thread.sleep(1234); // 模拟耗时操作
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.calculate();
    }
}

输出:

四、还能更优雅吗?Lambda 表达式!

如果你用的是 Java 8+,匿名内部类还能进一步简化。给 TimeCalculator 加个函数式接口的 "马甲":

java 复制代码
@FunctionalInterface
public interface TimeCalculator {
    
    static void calculate(TimeTask task) {
        long start = System.currentTimeMillis();
        task.execute();
        long end = System.currentTimeMillis();
        System.out.println("方法执行耗时: " + (end - start) + "ms");
    }
}

@FunctionalInterface
interface TimeTask {
    void execute();
}

使用时代码清爽到飞起:

java 复制代码
public class Demo {
    public static void main(String[] args) {
        TimeCalculator.calculate(() -> {
            // 你的业务代码
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

五、匿名内部类的使用场景总结

通过这次实践,我梳理了匿名内部类特别适合的场景:

场景 说明
一次性实现 只需要用一次的类,没必要单独写一个文件
回调机制 如线程的 Runnable、按钮的点击事件监听
模板方法 像本文这样,把不变的部分封装,变化的部分现场实现
函数式接口 Java 8 后推荐用 Lambda 替代,但原理相通

六、写在最后

匿名内部类看似只是 "省了一个类文件",但它的真正价值在于让代码更贴近思考方式------ 当你只想专注于 "我要做什么",而不想被 "怎么组织类" 分心时,它就是最好的选择。

当然,如果逻辑复杂、复用性高,还是乖乖写成独立类吧。技术没有银弹,只有合适的场景。

💬 思考题:你还能想到哪些用匿名内部类(或 Lambda)优化代码结构的场景?欢迎在评论区交流!

相关推荐
程序员清风8 小时前
推荐几个我常听的AI播客!
java·后端·面试
唐青枫9 小时前
Java Gradle 实战指南:从 Wrapper、Kotlin DSL 到 Spring Boot 多模块构建
java·kotlin·gradle
wuqingshun3141599 小时前
如何理解Spring Boot中的starter?
java·spring boot·后端
带刺的坐椅9 小时前
Solon TeamAgent 协作协议:从 SEQUENTIAL 流水线到 HIERARCHICAL 主管团队
java·ai·llm·agent·solon
wuqingshun3141599 小时前
SpringBoot是如何实现自动配置的
java·spring boot·后端
用户053704031439 小时前
我的学习记录泛型
java
zhouhui0019 小时前
AI帮我写了个Spring Boot校验,线上漏掉了这组边界条件
java·spring boot·redis·ai编程
JRedisX9 小时前
Java从零手写企业级内存数据库
java
萧瑟余晖9 小时前
JDK 20 新特性详解
java·开发语言
hdsoft_huge9 小时前
SpringBoot系列17:日志体系Logback配置,日志分割、脱敏、异常堆栈收集规范(生产级落地)
java·spring boot·logback