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

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

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

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)优化代码结构的场景?欢迎在评论区交流!

相关推荐
EXI-小洲6 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
2601_961901707 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
何以解忧,唯有..7 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
QQ_21696290968 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
前端 贾公子9 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_962203519 小时前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理9 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
roman_日积跬步-终至千里10 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
workflower10 小时前
人形机器人灵巧手产业链
人工智能·设计模式·机器人·云计算·无人机
落魄大学生之流水线上谋生计10 小时前
LangGraph 基本用法指南
java·windows·python·langchain