java 对象结构_Java基础系列(十):对象构造

默认域初始化

如果在构造器中没有显式地给域赋予初值,如下这样:

private String name;

private double salary;

//默认域初始化

public User() {

}

private String name;

private double salary;

//默认域初始化

public User() {

}

那么就会自动地赋为默认值:数值为0,布尔值为false,对象为null,但是我们一般不建议这么做,这样会大大的增加了阅读程序的难度,比如说上面的程序中,name被初始化为null,当我们调用一个新建User对象的 getName()方法,就会抛出一个空指针异常。所以,我们应该在初始化域的时候尽量不要采用默认值,而是赋予一些有意义的初始值。

无参构造

很多类都包含一个无参数的构造函数,对象由无参构造函数创建的时候,它的状态会被设置成适当的默认值,比如:

private String name;

private double salary;

//无参构造,初始化值

public User() {

name = "";

salary = 0;

}

private String name;

private double salary;

//无参构造,初始化值

public User() {

name = "";

salary = 0;

}

如果在编写一个类的时候忘记写构造器,不用担心,系统会提供一个无参的构造器,这个构造器将所有的实例域都设置为默认值,但是需要注意一点,如果类中提供了至少一个构造器,但是却没有提供无参构造,则在构造对象的时候没有提供参数就会视为不合法。 也就是说,仅仅当类没有提供任何构造器的时候,系统才会提供一个无参的构造器,如果在编写类的时候,给出了一个构造器,如果想要使用 newClassName()来构造对象,就必须提供一个默认的构造器(即不带参数的构造器)。

显式域初始化

当一个类的所有构造器都希望把相同的值赋予某个特定的实例域时,我们可以在类定义中,直接将一个值赋给这个特定的域:

class User {

private String name = "";

}

class User {

private String name = "";

}

当然,初始域也不一定非要是常量值,也可以调用方法对域进行初始化,比如我们使用方法来初始化User类的id,达到自动赋值的效果:

class User {

private static int nextId;

private int id = assignId();

private static int assignId() {

int r = nextId;

nextId++;

return r;

}

}

class User {

private static int nextId;

private int id = assignId();

private static int assignId() {

int r = nextId;

nextId++;

return r;

}

}

参数名

一般来说,我们在使用有参数的构造函数时,通常会用到this关键字用来区分实例域和参数名:

public User(String name, double salary) {

this.name = name;

this.salary = salary;

}

public User(String name, double salary) {

this.name = name;

this.salary = salary;

}

调用另一个构造器

如果构造器的第一个语句形如this(...),这个构造器将调用同一个类的另一个构造器,比如:

public User(double s) {

this("User #" + nextId, s)

nextId++;

}

public User(double s) {

this("User #" + nextId, s)

nextId++;

}

比如我们调用new User(3000)时候,User(double) 构造器将调用User(String, double)构造器。

采用着这种方式使用this关键字很有用,这样对公共的构造器代码部分只编写一次即可。

初始化块

在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行。比如:

class User {

private static int nextId;

private int id;

private String name;

private double salary;

{

id = nextId;

nextId++;

}

public User(String name, double salary) {

this.name = name;

this.salary = salary;

}

public User() {

this.name = "";

this.salary = 0

}

}

class User {

private static int nextId;

private int id;

private String name;

private double salary;

{

id = nextId;

nextId++;

}

public User(String name, double salary) {

this.name = name;

this.salary = salary;

}

public User() {

this.name = "";

this.salary = 0

}

}

在这个实例中,无论使用哪个构造器构造对象,id域都在对象初始化块中被初始化,首先运行初始化块,然后才运行构造器的主体部分。

总结

上面我们一共说了三种构造器,下面时调用构造器的具体处理步骤

所有数据域被初始化为默认值(0,false或null)

按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块

如果构造器第一行调用了第二个构造器,则执行第二个构造器主体

执行构造器主体。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值