Java 面向对象:构造方法与静态成员
构造方法决定对象”出生时的样子”,static 决定数据”属于类还是属于对象”。本篇讲透构造方法的调用时机与重载、代码块的执行顺序、static 的共享语义和工具类的标准写法,最后逐词拆解 main 方法签名。
本篇目标
- 掌握构造方法的格式、调用时机与重载规则
- 理清
new Student()背后的完整流程 - 分清构造代码块与静态代码块的执行时机
- 理解 static 的”类级别共享”语义及访问限制
- 会写工具类,能逐词解释 main 方法签名
构造方法:对象一出生就初始化
普通方法要建完对象再手动调,构造方法在 new 的瞬间由 JVM 自动调用,专门给属性赋初值。格式三个特点:方法名与类名完全一致(大小写也一样);没有返回值类型,连 void 都不写;方法体里不需要 return。
class Student { |
关键规则:一个构造都不写,系统免费赠送无参构造;一旦自己写了任何构造,系统不再赠送。所以”永远手写无参构造”是开发习惯,否则框架反射创建对象时会翻车。构造方法同样支持重载:方法名相同、参数列表不同即可,与返回值无关(本来也没有)。给属性赋值有两条路:构造方法负责”出生时初始化”,setXxx 负责”出生后修改”,实际开发中后者用得更多,因为灵活。
创建一个对象到底做了什么
Student s = new Student(); 的完整流程:Student.class 加载进方法区;栈中声明引用 s;堆中创建对象;属性默认初始化(null/0);显式初始化(定义时赋的值);构造代码块、构造方法依次进栈执行完弹栈;对象地址赋给 s。记住这个顺序,继承章节的”先父后子”是它的延伸。
构造代码块与静态代码块
类中方法外的一对 {} 是构造代码块:每次 new 都执行,且先于构造方法,适合提取多个构造的公共逻辑。加 static 的 static {} 是静态代码块:随类加载执行,只执行一次,常用于加载驱动、初始化静态资源。顺序口诀:静态代码块(类加载时,一次)→ 构造代码块(每次 new,构造方法之前)→ 构造方法。方法内部的局部代码块则用于限定变量生命周期,及早释放内存。
static:从”每对象一份”到”全类一份”
引入案例:Person 类的国籍字段,每个对象各存一份”中国”纯属浪费。加 static 后字段被所有对象共享、只存一份——就像教室里饮水机是共享的(静态),水杯人手一个(非静态)。共性用静态,特性用非静态,这就是该不该加 static 的判断标准。
四个特点:随类的加载而加载,存在方法区;优先于对象存在;被所有对象共享;推荐用 类名.静态成员 调用(对象名也能调,但不推荐)。
两条硬限制:静态方法里没有 this——静态随类加载,this 随对象创建,静态先存在,手里根本没有当前对象;静态方法只能直接访问静态成员,因为非静态成员属于某个具体对象,而此刻对象可能还没出生。反过来非静态方法访问什么都没限制。记法:静态只能访问静态。
静态变量与成员变量的区别
| 维度 | 静态变量(类变量) | 成员变量(实例变量) |
|---|---|---|
| 所属 | 类 | 对象 |
| 内存位置 | 方法区静态区 | 堆 |
| 出现时机 | 随类加载,随类卸载消失 | 随对象创建,随对象回收消失 |
| 调用方式 | 类名.变量名(推荐) | 只能对象名.变量名 |
工具类设计:ArrayTool 模式
操作数组的取最大值、遍历、反转等方法不需要任何对象状态,全部声明为 static,再把构造方法 private 掉,防止别人无意义地 new——JDK 的 Math、Arrays 都是这个设计:
public class ArrayTool { |
调用即 ArrayTool.getMax(arr)。配合文档注释(@author、@version、@param、@return),执行 javadoc -d doc -author -version ArrayTool.java 还能生成 API 说明书,这也是阅读 JDK 帮助文档的方法:先看包名要不要导包,再看构造方法怎么创建对象,最后按方法名查功能。
main 方法签名逐词解析
public static void main(String[] args) 是 JVM 的调用约定:public——JVM 要访问,权限必须足够大;static——启动时还没有任何对象,只能通过类名调用;void——返回值交给 JVM 没有意义;main——不是关键字,但 JVM 只认这个入口名;String[] args——接收命令行参数,java Demo a b c 时 args 就是 [“a”,”b”,”c”]。彩蛋:main 可以重载,但 JVM 只调字符串数组这个版本。
经典练习:猜数字小游戏
需求:程序生成 1-100 的随机数,循环提示玩家猜大猜小,直到命中。要点只有一个:用 int number = (int)(Math.random() * 100) + 1; 把 [0.0, 1.0) 映射到 1-100,配合 Scanner 循环输入即可。写完后把”比较大小并提示”抽成一个静态方法,体会工具方法的抽取过程。
小结
- 构造方法在 new 时自动调用,给对象初始化;自己写了构造,系统就不再送无参的。
- 静态代码块随类加载执行一次;构造代码块每次 new 执行且先于构造方法。
- static 语义是”类级别共享”:随类加载、全类一份、类名调用;静态方法无 this、只能访问静态成员。
- 工具类 = 私有构造 + 全静态方法;main 签名里每个词都是 JVM 调用的硬性要求。

