前几天在写一个数据处理模块时突然想测一下某个方法的耗时。第一反应是这样的public void doSomething() { long start System.currentTimeMillis(); // ... 业务逻辑 long end System.currentTimeMillis(); System.out.println(耗时: (end - start) ms); }写了几遍之后就开始烦躁了 ——每个方法都要复制粘贴这三行代码而且一旦不需要测速了还得一个个删掉代码变得又脏又乱。有没有一种更优雅的方式既能计算方法耗时又不污染业务代码二、思路把 测速 抽象成一个模板仔细一想这其实是一个经典的模板方法模式场景记录开始时间执行某个方法这是变化的记录结束时间并输出变化的只有第 2 步那能不能把这部分 抽出来 呢三、匿名内部类登场定义一个抽象类把不变的骨架写好把变化的部分留给子类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(); }然后在使用时匿名内部类就派上用场了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 加个函数式接口的 马甲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(); }使用时代码清爽到飞起public class Demo { public static void main(String[] args) { TimeCalculator.calculate(() - { // 你的业务代码 try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } }); } }五、匿名内部类的使用场景总结通过这次实践我梳理了匿名内部类特别适合的场景场景说明一次性实现只需要用一次的类没必要单独写一个文件回调机制如线程的 Runnable、按钮的点击事件监听模板方法像本文这样把不变的部分封装变化的部分现场实现函数式接口Java 8 后推荐用 Lambda 替代但原理相通六、写在最后匿名内部类看似只是 省了一个类文件但它的真正价值在于让代码更贴近思考方式—— 当你只想专注于 我要做什么而不想被 怎么组织类 分心时它就是最好的选择。当然如果逻辑复杂、复用性高还是乖乖写成独立类吧。技术没有银弹只有合适的场景。