Java构造方法

📅 2026/8/14 6:33:34
Java构造方法
1. 为什么需要构造方法代码冗余与遗漏风险创建对象后如果仅使用 setter 方法逐一初始化字段需要编写多行代码且容易遗漏调用某些 setter导致对象状态不完整。构造方法的优势构造方法允许在创建对象的瞬间完成所有必要字段的初始化使代码更简洁并强制提供完整初始状态从而更安全。示例对比使用 setter易出错PersonmingnewPerson();ming.setName(小明);ming.setAge(12);// 若忘记此调用age 将保持默认值 0使用构造方法推荐PersonmingnewPerson(小明,12);// 一行代码强制完成初始化2. 什么是构造方法构造方法是一种特殊方法用来在创建对象时初始化对象字段。语法示例classPerson{privateStringname;privateintage;// 构造方法publicPerson(Stringname,intage){this.namename;this.ageage;}publicStringgetName(){returnname;}publicintgetAge(){returnage;}}调用publicclassMain{publicstaticvoidmain(String[]args){PersonpnewPerson(小明,15);System.out.println(p.getName());// 小明System.out.println(p.getAge());// 15}}3. 构造方法的特点方法名必须和类名完全相同类叫 Person构造方法也必须叫 Person。2.没有返回值类型普通方法可能写成publicStringgetName()而构造方法不能写返回类型例如 public Person()不能写成 public void Person()。3.必须通过 new 调用构造方法不能像普通方法那样直接调用p.Person(小明,15);//错误PersonpnewPerson(小明,15);//new调用正确4.可以重载一个类可以有多个构造方法参数列表不同。4. 默认构造方法如果一个类没有定义任何构造方法编译器会自动生成一个无参构造方法。例如classPerson{privateStringname;privateintage;}编译器会自动生成类似这样的构造方法classPerson{privateStringname;privateintage;publicPerson(){// 空构造方法}}所以我们可以直接PersonpnewPerson();重要规则一旦你自己定义了任意一个构造方法编译器就不再自动生成默认无参构造方法。例如classPerson{privateStringname;privateintage;publicPerson(Stringname,intage){this.namename;this.ageage;}}这时再写PersonpnewPerson();// 编译错误找不到无参构造方法因为编译器不再自动提供 Person()。如果既想要无参构造方法又想要有参构造方法必须手动把两个都写出来classPerson{privateStringname;privateintage;publicPerson(){}publicPerson(Stringname,intage){this.namename;this.ageage;}}5. 字段默认值如果构造方法没有给字段赋值字段会使用默认值。类型 默认值 byte / short / int / long0float / double0.0char\u0000booleanfalse引用类型例如 String null示例publicclassMain{publicstaticvoidmain(String[]args){PersonpnewPerson();System.out.println(p.getName());//nullSystem.out.println(p.getAge());//0System.out.println(p.getVip());//false}}classPerson{privateStringname;privateintage;privatebooleanvip;publicPerson(){}publicPerson(Stringname,intage,booleanvip){this.namename;this.ageage;this.vipvip;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.namename;}publicintgetAge(){returnage;}publicbooleangetVip(){returnvip;}}6. 字段初始化器我们可以在声明字段时直接赋初值classPerson{privateStringname未命名;privateintage10;}这样即使构造方法没有给字段赋值字段也有默认的初始值。7. 构造方法重载重载在同一个类中允许定义多个构造方法只要它们的参数列表不同参数个数、类型或顺序不同。重载的目的提供多种创建对象的方式让使用者可以根据实际情况灵活传参而不必为每种情况写不同的方法名。classPerson{privateStringname;privateintage;// 构造方法①两个参数publicPerson(Stringname,intage){this.namename;this.ageage;}// 构造方法②一个参数StringpublicPerson(Stringname){this.namename;this.age18;}// 构造方法③无参数publicPerson(){}}调用时编译器会根据参数自动匹配当你用 new 创建对象并传入实参时编译器会根据实参的个数、类型和顺序去匹配最合适的构造方法。Personp1newPerson(小明,20);// 调用 Person(String, int)/* 传入实参小明String、20int 匹配到构造方法① Person(String, int) 执行this.name 小明this.age 20 结果p1 对象的 name 小明age 20 */Personp2newPerson(小红);// 调用 Person(String)Personp3newPerson();// 调用 Person()为什么要这样设计提供灵活性调用者可以只给名字年龄自动成年也可以给名字年龄甚至可以完全默认比如用于后续 setter 赋值。减少重复代码如果没有重载你可能需要写 setName()、setAge() 或者多个不同名的创建方法而重载让 new 本身就完成了差异化初始化。8. 用 this(…) 调用其他构造方法一个构造方法可以调用另一个构造方法语法是 this(参数…)。作用复用初始化逻辑避免重复代码。classPerson{privateStringname;privateintage;publicPerson(Stringname,intage){this.namename;this.ageage;}publicPerson(Stringname){this(name,18);// 调用 Person(String, int)}publicPerson(){this(未命名);// 调用 Person(String)}}注意this(…) 必须写在构造方法的第一行。错误写法publicPerson(){System.out.println(初始化);this(未命名);// 编译错误this(...)必须放在第一行}9. 字段初始化与构造方法的执行顺序创建对象时Java 按以下顺序初始化先给字段分配默认值例如 String name 先变成 nullint age 先变成 0。执行字段初始化器例如privateStringname未命名;privateintage10;这时 name 变成 “未命名”age 变成 10。执行构造方法体的代码如果构造方法体中再次给字段赋值会覆盖前面的值。1.先给字段分配默认值。例如 String name 先变成 nullint age 先变成 0。2.执行字段初始化器。例如privateStringname未命名;privateintage10;这时 name 变成 “未命名”age 变成 10。执行构造方法体的代码。如果构造方法体中再次给字段赋值会覆盖前面的值。示例classPerson{privateStringname未命名;privateintage10;publicPerson(Stringname,intage){this.namename;this.ageage;}}执行PersonpnewPerson(小明,12);过程name 初始为 nullage 初始为 0字段初始化器执行name “未命名”age 10构造方法体执行name “小明”age 12最终结果javap.getName(); // 小明p.getAge(); // 12所以字段初始化器先执行构造方法体后执行最终值由构造方法体决定。publicclassMain{publicstaticvoidmain(String[]args){System.out.println( 开始执行 new Person(\小明\, 12) );PersonpnewPerson(小明,12);System.out.println( new 操作执行完毕 );p.show();}}classPerson{// 1. 字段定义 字段初始化器 (带打印)privateStringname未命名;privateintage10;// 2. 实例初始化块 (它在字段初始化器之后、构造方法体之前执行){System.out.println(【步骤3】执行 实例初始化块 { } 内的代码);System.out.println( 此时 name name, age age);// 假设这里偷偷改一下年龄看看会不会被构造方法覆盖this.age99;System.out.println( 初始化块执行完毕age 被改为 99);}// 3. 构造方法体publicPerson(Stringname,intage){System.out.println(【步骤4】进入 构造方法体 public Person(String name, int age));System.out.println( 执行构造方法前this.name this.name, this.age this.age);this.namename;this.ageage;System.out.println( 执行构造方法后this.name this.name, this.age this.age);}// 用来查看最终结果的普通方法publicvoidshow(){System.out.println(【最终对象结果】name name, age age);}}