阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

构造方法

82次阅读
没有评论

共计 3288 个字符,预计需要花费 9 分钟才能阅读完成。

创建实例的时候,我们经常需要同时初始化这个实例的字段,例如:

Person ming = new Person();
ming.setName("小明");
ming.setAge(12);

初始化对象实例需要 3 行代码,而且,如果忘了调用 setName() 或者setAge(),这个实例内部的状态就是不正确的。

能否在创建对象实例时就把内部字段全部初始化为合适的值?

完全可以。

这时,我们就需要构造方法。

创建实例的时候,实际上是通过构造方法来初始化实例的。我们先来定义一个构造方法,能在创建 Person 实例的时候,一次性传入 nameage,完成初始化:

// 构造方法
public class Main {public static void main(String[] args) {Person p = new Person("Xiao Ming", 15);
        System.out.println(p.getName());
        System.out.println(p.getAge());
    }
}

class Person {private String name;
    private int age;

    public Person(String name, int age) {this.name = name;
        this.age = age;
    }
    
    public String getName() {return this.name;
    }

    public int getAge() {return this.age;
    }
}

由于构造方法是如此特殊,所以构造方法的名称就是类名。构造方法的参数没有限制,在方法内部,也可以编写任意语句。但是,和普通方法相比,构造方法没有返回值(也没有 void),调用构造方法,必须用new 操作符。

默认构造方法

是不是任何 class 都有构造方法?是的。

那前面我们并没有为 Person 类编写构造方法,为什么可以调用new Person()

原因是如果一个类没有定义构造方法,编译器会自动为我们生成一个默认构造方法,它没有参数,也没有执行语句,类似这样:

class Person {public Person() {}}

要特别注意的是,如果我们自定义了一个构造方法,那么,编译器就 不再 自动创建默认构造方法:

// 构造方法
public class Main {public static void main(String[] args) {Person p = new Person(); // 编译错误: 找不到这个构造方法
    }
}

class Person {private String name;
    private int age;

    public Person(String name, int age) {this.name = name;
        this.age = age;
    }
    
    public String getName() {return this.name;
    }

    public int getAge() {return this.age;
    }
}

如果既要能使用带参数的构造方法,又想保留不带参数的构造方法,那么只能把两个构造方法都定义出来:

// 构造方法
public class Main {public static void main(String[] args) {Person p1 = new Person("Xiao Ming", 15); // 既可以调用带参数的构造方法
        Person p2 = new Person(); // 也可以调用无参数构造方法
    }
}

class Person {private String name;
    private int age;

    public Person() { }

    public Person(String name, int age) {this.name = name;
        this.age = age;
    }
    
    public String getName() {return this.name;
    }

    public int getAge() {return this.age;
    }
}

没有在构造方法中初始化字段时,引用类型的字段默认是 null,数值类型的字段用默认值,int 类型默认值是0,布尔类型默认值是false

class Person {private String name; // 默认初始化为 null
    private int age; // 默认初始化为 0 

    public Person() {}}

也可以对字段直接进行初始化:

class Person {private String name = "Unamed";
    private int age = 10;
}

那么问题来了:既对字段进行初始化,又在构造方法中对字段进行初始化:

class Person {private String name = "Unamed";
    private int age = 10;

    public Person(String name, int age) {this.name = name;
        this.age = age;
    }
}

当我们创建对象的时候,new Person("Xiao Ming", 12)得到的对象实例,字段的初始值是啥?

在 Java 中,创建对象实例的时候,按照如下顺序进行初始化:

  1. 先初始化字段,例如,int age = 10;表示字段初始化为 10double salary; 表示字段默认初始化为 0String name; 表示引用类型字段默认初始化为null
  2. 执行构造方法的代码进行初始化。

因此,构造方法的代码由于后运行,所以,new Person("Xiao Ming", 12)的字段值最终由构造方法的代码确定。

多个构造方法

可以定义多个构造方法,在通过 new 操作符调用的时候,编译器通过构造方法的参数数量、位置和类型自动区分:

class Person {private String name;
    private int age;

    public Person(String name, int age) {this.name = name;
        this.age = age;
    }

    public Person(String name) {this.name = name;
        this.age = 12;
    }

    public Person() {}}

如果调用new Person("Xiao Ming", 20);,会自动匹配到构造方法public Person(String, int)

如果调用new Person("Xiao Ming");,会自动匹配到构造方法public Person(String)

如果调用new Person();,会自动匹配到构造方法public Person()

一个构造方法可以调用其他构造方法,这样做的目的是便于代码复用。调用其他构造方法的语法是this(…)

class Person {private String name;
    private int age;

    public Person(String name, int age) {this.name = name;
        this.age = age;
    }

    public Person(String name) {this(name, 18); // 调用另一个构造方法 Person(String, int)
    }

    public Person() {this("Unnamed"); // 调用另一个构造方法 Person(String)
    }
}

练习

请给 Person 类增加 (String, int) 的构造方法:

public class Main {public static void main(String[] args) {// TODO: 给 Person 增加构造方法:
        Person ming = new Person("小明", 12);
        System.out.println(ming.getName());
        System.out.println(ming.getAge());
    }
}

class Person {private String name;
    private int age;

    public String getName() {return name;
    }

    public int getAge() {return age;
    }
}

下载练习

小结

实例在创建时通过 new 操作符会调用其对应的构造方法,构造方法用于初始化实例;

没有定义构造方法时,编译器会自动创建一个默认的无参数构造方法;

可以定义多个构造方法,编译器根据参数自动判断;

可以在一个构造方法内部调用另一个构造方法,便于代码复用。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计3288字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中