第四次博客作业:从计算耗时到匿名内部类,一次关于代码优化的思考

  1. 精准计时

假设有一个复杂的算法 doSomething() ,想知道它跑完到底需要多久。最直观的想法是:
long start = System.currentTimeMillis();
doSomething(); // 执行业务逻辑
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");

这段代码没问题,但如果有 100 个方法需要测试时,若把这三行代码复制粘贴 100 次,显然违反了 DRY(Don't Repeat Yourself) 原则。

  1. 进阶思路:封装通用逻辑

为了解决重复代码的问题,想到封装一个工具方法。可以定义一个接口 Task ,里面有一个  execute()  方法。

interface Task {
void execute();
}

public class Timer {
public static void timeIt(Task task) {
long start = System.currentTimeMillis();
task.execute(); // 这里执行具体的业务逻辑
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
}
}
这样一来,我们只需要调用  Timer.timeIt(...)  就可以复用计时的逻辑了。

  1. 痛点出现:为了用一次而写一个类?

现在问题来了:每次调用  timeIt  方法时,我们需要传入一个实现了 Task  接口的对象。

如果按照传统的面向对象写法,我们需要这样做:

新建一个文件  MyHeavyTask.java 。
让它  implements Task 。
在  execute  方法里写上那堆复杂的业务代码。
实例化  new MyHeavyTask()  传给  timeIt 。

这样显然太麻烦了! 如果这个任务只是在这里用一次,专门去创建一个完整的类文件,不仅让项目文件变得臃肿,而且阅读代码时还要跳来跳去,非常不直观。

  1. 救星登场:匿名内部类

这时候,匿名内部类就闪亮登场了。正如 PPT 上提到的 “匿名内部类的使用场景”,它最适合解决这种 “只需要使用一次的类” 的情况。

我们可以直接在方法调用的参数里,“现场”定义并实例化这个类:
Timer.timeIt(new Task() {
@Override
public void execute() {
// 这里直接写你的复杂业务逻辑
for(int i=0; i<100000; i++) {
Math.random();
}
}
});
Timer.timeIt(new Task() {
@Override
public void execute() {
// 这里直接写你的复杂业务逻辑
for(int i=0; i<100000; i++) {
Math.random();
}
}
});
此时没有类名,没有额外的文件,代码紧凑且逻辑连贯。这就是匿名内部类的魅力。

  1. 总结:什么时候该用它?

结合homework1,可以总结出匿名内部类的核心使用场景:

简化代码:当某个接口的实现类只需要使用一次时。

回调机制:像 Android 开发中的按钮点击事件  setOnClickListener ,或者这里的计时器回调,都是典型的例子。

逻辑内聚:让业务逻辑和调用它的地方紧挨在一起,提高代码的可读性。

posted @ 2026-06-07 22:43  定缘  阅读(22)  评论(0)    收藏  举报