前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java基础系列(十):对象构造

Java基础系列(十):对象构造

作者头像
山禾说
发布2019-01-21 10:01:31
3710
发布2019-01-21 10:01:31
举报
文章被收录于专栏:Vi的技术博客Vi的技术博客
默认域初始化

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

代码语言:javascript
复制
private String name;
private double salary;

//默认域初始化
public User() {

}

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

无参构造

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

代码语言:javascript
复制
private String name;
private double salary;

//无参构造,初始化值
public User() {
    name = "";
    salary = 0;
}

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

显式域初始化

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

代码语言:javascript
复制
class User {

    private String name = "";
}

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

代码语言:javascript
复制
class User {

    private static int nextId;

    private int id = assignId();

    private static int assignId() {
        int r = nextId;
        nextId++;
        return r;
    }
}
参数名

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

代码语言:javascript
复制
public User(String name, double salary) {
    this.name = name;
    this.salary = salary;
}
调用另一个构造器

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

代码语言:javascript
复制
public User(double s) {

    this("User #" + nextId, s)
    nextId++;
}

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

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

初始化块

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

代码语言:javascript
复制
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域都在对象初始化块中被初始化,首先运行初始化块,然后才运行构造器的主体部分。

总结

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

  1. 所有数据域被初始化为默认值(0,false或null)
  2. 按照在类声明中出现的次序,依次执行所有域初始化语句和初始化块
  3. 如果构造器第一行调用了第二个构造器,则执行第二个构造器主体
  4. 执行构造器主体。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Vi的技术博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 默认域初始化
  • 无参构造
  • 显式域初始化
  • 参数名
  • 调用另一个构造器
  • 初始化块
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档