System 是一个不能 new 的系统工具箱:成员全是 static,类名直接点——out 打印、currentTimeMillis 秒表、exit 停机、arraycopy 搬数组。3.6/3.7 的 static 知识在这里第一次大规模实战。
3.6 代码块 与 3.7 static关键字(static 静态成员的规矩)、2.7 数组(arraycopy 的主场)、第六章 Java API/6.2 字符串类(循环 + 拼接的坑,本节用秒表实测)。
1. System 是什么?——一个"开不了门"的类
System.out.println("Hello"); // 用了一个月,今天正式认识
System 类的构造方法是私有的(private),new 不出来——全世界就一份,所有成员都是 static,用类名直接点调用:
System.out // 字段:标准输出流
System.err // 字段:标准错误流(红色字)
System.in // 字段:标准输入流(键盘,后面配 Scanner)
工具类不需要多个实例——一份就够。构造私有 + 成员全 static 是工具类的标准设计套路(Math、Arrays、Integer.parseInt 全是同一套路)。3.6/3.7 学 static 时说"工具箱方法挂在类上",这就是实物。
2. currentTimeMillis():系统秒表
long now = System.currentTimeMillis();
System.out.println(now); // 例如 1789476245123
返回从 1970-1-1 00:00:00 到现在的总毫秒数(计算机的"纪元起点",1.4 讲运行机制时提过)。这个数本身没啥用,差值才是精华——夹逼测耗时:
long start = System.currentTimeMillis(); // 起表
for (int i = 0; i < 100000; i++) {
s = s + i; // 循环狂拼字符串
}
long end = System.currentTimeMillis(); // 停表
System.out.println("耗时:" + (end - start) + " 毫秒");
这个套路到处都用:测算法快慢、接口响应时间,全是它。
3. exit(int status):总闸停机
System.exit(0); // 0 = 正常退出;非 0 = 异常退出
JVM 直接停机——比 return 狠得多:return 只是结束当前方法,exit 是整个程序原地断电。
5.3 学过"finally 两路必跑,System.exit 除外"——就是它。一按停机,finally、后面的代码统统不跑。急着退出时才用,别当 return 用。
4. arraycopy():数组搬运工(五参数)
int[] src = {10, 20, 30, 40, 50};
int[] dest = new int[5];
System.arraycopy(src, 1, dest, 0, 3);
// dest = {20, 30, 40, 0, 0}
五参数口诀:从哪 · 起步 · 到哪 · 放哪 · 搬几个
| 参数 | 含义 | 示例值 |
|---|---|---|
| src | 源数组(从哪复制) | src |
| srcPos | 从源的下标几开始 | 1 |
| dest | 目标数组(到哪) | dest |
| destPos | 放到目标的下标几 | 0 |
| length | 一共搬几个 | 3 |
比 2.7 手写 for 循环复制快(底层是内存级拷贝),Arrays.copyOf 的底层也是它——工具箱里藏着的"基础设施"。
5. gc():跟 JVM 打个招呼(了解)
System.gc() 建议 JVM 收垃圾。只是"建议"——什么时候真收 JVM 说了算。新手期记住一句:Java 的内存回收是自动的,不用你操心,知道有这号人物即可。
6. 动手环节(IDEA06 · Demo03)
- 写
Demo03,先打印System.currentTimeMillis(),跑一遍看看这个大数。 - 夹逼秒表:循环 10 万次
s += i拼字符串,打印耗时。成功标准:控制台给出一个毫秒数(几百到几千不等)。 - 30 秒实验 ①:把循环改成
for (int i = 0; i < 100000; i++) sb.append(i);(StringBuilder 语法下节讲,先照抄)→ 对比耗时,差距通常几十倍——6.2 埋的钩子用数据收网。 - 30 秒实验 ②:try-finally 里写
System.exit(0);→ finally 里的打印没出现,亲眼看"finaly 拦不住停机"。 - 30 秒实验 ③:arraycopy 按"从哪·起步·到哪·放哪·搬几个"口诀改五组参数,每次打印 dest 验证理解。
7. 常见误区
- 想 new System() → 构造私有,编不过。工具类全是类名直接点。
- 拿 currentTimeMillis 的返回值当日期看 → 它是 1970 起的总毫秒数,不是"现在几点"(要日期用日期类,后面学)。
- exit 当 return 用 → return 结束方法,exit 结束整个程序,还能跳过 finally。
- arraycopy 五参数背顺序 → 别死背,记口诀"从哪·起步·到哪·放哪·搬几个"。
8. 本节小结
| 要点 | 内容 |
|---|---|
| 身份 | 构造私有的工具类,成员全 static,类名直接点 |
| out / err / in | 标准(输出/错误/输入)流 |
| currentTimeMillis | 1970 起的毫秒数;夹逼秒表测耗时 |
| exit | 总闸停机,finally 都拦不住 |
| arraycopy | 五参数数组搬运工,底层基础设施 |
| gc | 建议 JVM 收垃圾(了解) |
9. 可折叠自测题
构造方法被 private 修饰,外部无法创建实例。它的成员全是 static(静态成员属于类不属于对象),所以直接 System.out、System.currentTimeMillis() 用类名调用——3.7 static 的标准应用。
起表 long start = System.currentTimeMillis(); → 跑被测代码 → 停表 long end = ...,end - start 就是毫秒耗时。本质:两次取当前毫秒值求差。
从 arr 的下标 2 开始,复制到 brr 的下标 1 开始的位置,一共搬 4 个元素。口诀:从哪(arr)·起步(2)·到哪(brr)·放哪(1)·搬几个(4)。
不跑。不矛盾——return 只是"结束方法但程序还活着",JVM 有空跑 finally;exit 是"程序直接断电",没有"之后"可言。5.3 讲的"finally 两路必跑"本来就注明了 exit 例外。
long start = System.currentTimeMillis();
String s = "";
for (int i = 0; i < 100000; i++) s += i;
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + " 毫秒");
慢的原因:String 不可变(6.2),每次 += 都要造新对象再拷贝旧内容——10 万次就是 10 万批新对象。解法是 6.3 之后的 StringBuilder,可变容器攒完再一次性变 String。
10. 下一步学什么
- ☑ 6.4 Math类和Random类 ✅ —— 取整三兄弟 + 任意范围随机数公式 + 猜数字游戏,工具类套路原样复用。点此复习
相关笔记
- 第六章 Java API/6.2 字符串类 ← 上一篇:循环 + 拼接的坑,本节用秒表拿实测数据
- 3.7 static关键字:静态成员规矩,工具类设计套路的本体课
- 2.7 数组:arraycopy 的主场,手写复制 vs 内存级复制
- 5.3 异常处理及语法:"finally 两路必跑,exit 除外"的出处