Java作业:使用匿名内部类计算方法执行时间

一、作业需求

计算一个方法执行了多少秒(或毫秒),要求使用匿名内部类实现。

这是一个典型的应用场景:在不修改原有方法代码的情况下,为方法添加执行时间统计功能。

二、什么是匿名内部类?

2.1 定义

匿名内部类(Anonymous Inner Class)是没有名字的内部类,通常用于一次性使用的场景。

2.2 基本语法
匿名内部类 语法示例
匿名内部类的标准语法格式如下,适用于直接实现接口或继承父类并重写方法:

父类/接口 变量名 = new 父类/接口() {
@Override
返回类型 方法名(参数列表) {
// 方法实现
}
};
AI写代码
java
运行
具体实现案例
实现接口示例(Runnable):

Runnable task = new Runnable() {
@Override
public void run() {
System.out.println(“匿名内部类执行任务”);
}
};
AI写代码
java
运行
继承抽象类示例(Thread):

Thread thread = new Thread() {
@Override
public void run() {
System.out.println(“重写Thread的run方法”);
}
};
AI写代码
java
运行
使用场景说明
适用于需要一次性使用的类实现,避免单独创建子类文件
常用于事件监听、线程实现等需要快速重写方法的场景
匿名内部类会隐式持有外部类的引用,需注意内存泄漏问题
语法要点
必须实现父类或接口的所有抽象方法
可以访问外部类的final变量或等效final变量
编译后会生成独立的.class文件,命名格式为外部类$数字.class
Lambda简化场景
当接口仅含单个抽象方法时(函数式接口),可用Lambda表达式替代:

Runnable task = () -> System.out.println(“Lambda替代匿名类”);
AI写代码
java
运行
2.3 特点
特点 说明
没有类名 创建时直接定义类体
一次性使用 通常只使用一次
简化代码 避免单独定义一个类
必须实现所有抽象方法 与普通类相同
三、设计思路
3.1 核心问题
如何在不修改原有方法代码的情况下,统计方法的执行时间?

3.2 解决方案
使用模板方法设计模式 + 匿名内部类:

定义一个接口或抽象类,包含需要执行的方法

在工具类中编写计时方法,接收接口/抽象类的实现

调用时使用匿名内部类传入具体逻辑

3.3 流程图
以下是基于文本描述的计时流程实现方案,采用Java代码示例和流程图说明:

代码实现方案
// 定义函数式接口,便于匿名内部类实现
@FunctionalInterface
interface TargetMethod {
void execute();
}

public class TimeRecorder {
public static void recordExecutionTime(TargetMethod method) {
long startTime = System.nanoTime();
method.execute();
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println(“Execution time: “ + duration + “ ns”);
}

public static void main(String[] args) {
    // 通过匿名内部类实现目标方法
    recordExecutionTime(new TargetMethod() {
        @Override
        public void execute() {
            // 替换为实际需要计时的代码
            int sum = 0;
            for (int i = 0; i < 1000000; i++) {
                sum += i;
            }
        }
    });
}

}
AI写代码
java
运行

流程图表示
text

开始计时

记录开始时间 (startTime)

执行目标方法 ←──── 匿名内部类提供具体实现

记录结束时间 (endTime)

计算耗时 = endTime - startTime

输出结果
关键说明
时间精度:使用System.nanoTime()获取纳秒级时间戳,比currentTimeMillis()精度更高
函数式接口:通过接口设计使计时逻辑与业务逻辑解耦
Lambda优化:Java 8+可使用Lambda简化匿名内部类写法:
recordExecutionTime(() -> {
int sum = IntStream.range(0, 1000000).sum();
});
AI写代码
java
运行
注意事项
避免在测试方法中包含IO操作或随机因素
考虑JVM预热问题,正式测试前应先执行几次预热运行
对于微基准测试建议使用JMH等专业框架
四、代码实现
4.1 方式一:使用接口
以下是整理后的代码块格式:

/**

  • 定义一个接口,包含需要计时的方法
    */
    interface Task {
    void execute(); // 需要执行的任务
    }

/**

  • 计时器工具类
    /
    class TimerUtil {
    /
    *
    • 计算任务执行时间(毫秒)
    • @param task 要执行的任务
      */
      public static void measureTime(Task task) {
      long startTime = System.currentTimeMillis();
      task.execute();
      long endTime = System.currentTimeMillis();
      long duration = endTime - startTime;
      System.out.println(“方法执行耗时:” + duration + “ 毫秒”);
      System.out.println(“转换为秒:” + duration / 1000.0 + “ 秒”);
      }
      }

/**

  • 测试类
    */
    public class TimeTest {
    public static void main(String[] args) {
    TimerUtil.measureTime(new Task() {
    @Override
    public void execute() {
    System.out.println(“开始执行任务…”);
    for (int i = 0; i < 100000000; i++) {
    Math.sqrt(i);
    }
    System.out.println(“任务执行完毕”);
    }
    });
    }
    }
    AI写代码
    java
    运行

运行结果:

开始执行任务…
任务执行完毕
方法执行耗时:12 毫秒
转换为秒:0.012 秒
AI写代码
text
4.2 方式二:使用抽象类
/**

  • 抽象类:需要计时的任务
    */
    abstract class AbstractTask {
    public abstract void run();
    }

/**

  • 计时器工具类(支持抽象类)
    */
    class TimerUtil2 {
    public static void measureTime(AbstractTask task) {
    long startTime = System.nanoTime(); // 纳秒,更精确

    task.run();

    long endTime = System.nanoTime();
    long duration = endTime - startTime;

    System.out.println(“执行耗时:” + duration + “ 纳秒”);
    System.out.println(“转换为毫秒:” + duration / 1000000.0 + “ 毫秒”);
    }

}

/**

  • 测试类
    */
    public class TimeTest2 {
    public static void main(String[] args) {
    // 使用匿名内部类继承AbstractTask
    TimerUtil2.measureTime(new AbstractTask() {
    @Override
    public void run() {
    // 需要计时的业务逻辑
    System.out.println(“正在计算100以内素数…”);
    for (int i = 2; i <= 100; i++) {
    boolean isPrime = true;
    for (int j = 2; j <= Math.sqrt(i); j++) {
    if (i % j == 0) {
    isPrime = false;
    break;
    }
    }
    if (isPrime) {
    System.out.print(i + “ “);
    }
    }
    System.out.println();
    }
    });
    }
    }

AI写代码
java
运行

4.3 方式三:带返回值的方法计时

如果需要统计的方法有返回值,可以使用泛型:

/**

  • 带返回值的任务接口
  • @param 返回值类型
    */
    interface CallableTask {
    T execute();
    }

/**

  • 计时器工具类(支持返回值)
    */
    class TimerUtil3 {
    public static T measureTime(CallableTask task, String taskName) {
    System.out.println(“========== “ + taskName + “ ==========”);

    long startTime = System.currentTimeMillis();
    T result = task.execute();
    long endTime = System.currentTimeMillis();
    long duration = endTime - startTime;

    System.out.println(“执行耗时:” + duration + “ 毫秒(” + duration / 1000.0 + “ 秒)”);
    System.out.println(“================================”);

    return result;
    }

}

/**

  • 测试类
    */
    public class TimeTest3 {
    public static void main(String[] args) {
    // 计算1到100的和,并返回结果
    Integer sum = TimerUtil3.measureTime(new CallableTask() {
    @Override
    public Integer execute() {
    int total = 0;
    for (int i = 1; i <= 100; i++) {
    total += i;
    }
    System.out.println(“计算结果:” + total);
    return total;
    }
    }, “计算1-100的和”);

    System.out.println(“返回结果:” + sum);

    // 计算斐波那契数列
    TimerUtil3.measureTime(new CallableTask() {
    @Override
    public Void execute() {
    System.out.println(“斐波那契数列前20项:”);
    long a = 0, b = 1;
    for (int i = 0; i < 20; i++) {
    System.out.print(a + “ “);
    long temp = a + b;
    a = b;
    b = temp;
    }
    System.out.println();
    return null;
    }
    }, “斐波那契数列”);
    }

}

AI写代码
java
运行

五、多种时间单位说明

方法 返回单位 说明
System.currentTimeMillis() 毫秒 从1970-01-01到现在的毫秒数
System.nanoTime() 纳秒 高精度计时,适合短时间测量
以下是将时间单位转换的Java代码示例:

毫秒转秒
long ms = 1234;
double seconds = ms / 1000.0; // 结果为1.234秒
AI写代码
java
运行
纳秒转毫秒
long ns = 12345678;
double ms = ns / 1000000.0; // 结果为12.345678毫秒
AI写代码
java
运行
秒转毫秒
double seconds = 1.5;
long ms = (long)(seconds * 1000); // 结果为1500毫秒
AI写代码
java
运行
毫秒转纳秒
long ms = 15;
long ns = ms * 1000000L; // 结果为15000000纳秒
AI写代码
java
运行
注意事项:

使用浮点数除法(1000.0)确保精度不丢失
大数值计算时使用L后缀防止整数溢出
从浮点转整型时需要进行显式类型转换
六、不使用匿名内部类的对比
6.1 传统方式(单独定义一个类)
// 需要单独定义一个类
class MyTask implements Task {
@Override
public void execute() {
// 业务逻辑
}
}

// 使用时
TimerUtil.measureTime(new MyTask());
AI写代码
java
运行

6.2 使用匿名内部类的方式

TimerUtil.measureTime(new Task() {
@Override
public void execute() {
// 业务逻辑
}
});
AI写代码
java
运行
代码说明
使用匿名内部类实现Task接口
measureTime方法接收Task实例并测量其execute方法的执行时间
业务逻辑需在execute方法中实现
格式要点
代码块使用三个反引号加语言类型标记
保持原代码缩进结构
注释保留在原有位置
6.3 Lambda表达式方式(Java 8+)
// 更简洁的Lambda写法(接口只有一个抽象方法时)
TimerUtil.measureTime(() -> {
// 业务逻辑
});
AI写代码
java
运行
代码说明
使用Lambda表达式简化了匿名内部类的写法
适用于函数式接口(只有一个抽象方法的接口)
大括号内可编写需要计时的业务逻辑代码
代码块格式便于在Markdown文档中突出显示
注意事项
确保TimerUtil类已正确导入
measureTime方法需接收Runnable或Callable等函数式接口参数
Lambda表达式中的业务逻辑不应过于复杂
方式 代码量 可读性 适用场景
单独定义类 多 一般 需要多处复用
匿名内部类 中 较好 一次性使用
Lambda 少 好 接口只有一个抽象方法
七、完整示例:多个方法计时
以下是转换后的代码块格式:

/**

  • 综合示例:统计多个排序算法的执行时间
    */
    public class SortTimeTest {
    public static void main(String[] args) {
    // 准备测试数据
    int[] arr1 = generateRandomArray(10000);
    int[] arr2 = arr1.clone();

    // 测试冒泡排序时间
    TimerUtil.measureTime(new Task() {
    @Override
    public void execute() {
    bubbleSort(arr1.clone());
    System.out.println(“冒泡排序完成”);
    }
    });

    // 测试快速排序时间
    TimerUtil.measureTime(new Task() {
    @Override
    public void execute() {
    quickSort(arr2.clone(), 0, arr2.length - 1);
    System.out.println(“快速排序完成”);
    }
    });
    }

    /**

    • 生成随机数组
      */
      private static int[] generateRandomArray(int size) {
      int[] arr = new int[size];
      for (int i = 0; i < size; i++) {
      arr[i] = (int) (Math.random() * size);
      }
      return arr;
      }

    /**

    • 冒泡排序
      */
      private static void bubbleSort(int[] arr) {
      for (int i = 0; i < arr.length - 1; i++) {
      for (int j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
      int temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
      }
      }
      }
      }

    /**

    • 快速排序
      */
      private static void quickSort(int[] arr, int left, int right) {
      if (left >= right) return;
      int pivot = partition(arr, left, right);
      quickSort(arr, left, pivot - 1);
      quickSort(arr, pivot + 1, right);
      }

    private static int partition(int[] arr, int left, int right) {
    int pivot = arr[left];
    int i = left, j = right;
    while (i < j) {
    while (i < j && arr[j] >= pivot) j–;
    arr[i] = arr[j];
    while (i < j && arr[i] <= pivot) i++;
    arr[j] = arr[i];
    }
    arr[i] = pivot;
    return i;
    }

}
AI写代码
java
运行

八、总结

8.1 核心知识点
知识点 应用
匿名内部类 简化代码,一次性传入任务逻辑
接口/抽象类 定义任务规范
System.currentTimeMillis() 获取系统时间,计算耗时
模板方法模式 固定计时流程,任务逻辑可变
8.2 匿名内部类的使用场景
回调函数:如本作业的方法计时

事件监听:GUI编程中的按钮点击事件

线程创建:new Thread(new Runnable() {…})

集合排序:Collections.sort(list, new Comparator() {…})

8.3 作业完成情况
实现了方法执行时间计算功能

使用了匿名内部类

支持毫秒/纳秒两种精度

支持带返回值的场景

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2026 Shipanxs
  • 访问人数: | 浏览次数:

如果这篇文章对你有帮助,可以请我喝杯茶

支付宝

支付宝扫一扫