Java入门——对象的构造

您已经了解了如何编写定义对象初始状态的简单构造函数。但是,由于对象构造非常重要,因此Java提供了许多用于编写构造函数的机制。我们将在以下各节中介绍这些机制。

1.重载函数

有些类具有多个构造函数。例如,您可以将一个空的StringBuilder对象构造为

var messages = new StringBuilder();

另外,您可以指定一个初始字符串:

var todoList = new StringBuilder(“ To do:\ n”);

此功能称为 重载。如果多个方法具有相同的名称(在本例中为StringBuilder构造函数方法),但参数不同,则会发生重载。编译器必须整理出要调用的方法。它
通过将各种方法的标题中的参数类型与特定方法调用中使用的值的类型进行匹配,来选择正确的方法。

如果编译器无法匹配参数,则可能会发生编译时错误,这可能是因为根本没有匹配项,或者是因为没有一个匹配项优于所有其他参数。(找到匹配项的过程称为 重载解析。)

注意: Java允许您重载任何方法,而不仅仅是构造方法。

因此,要完整描述一种方法,您需要指定其名称以及其参数类型。这称为方法的 签名。例如,String类具有四个称为indexOf的公共方法。它们具有签名indexOf(int)

indexOf(int,int)

indexOf(String)

indexOf(String,int)

返回类型不是方法签名的一部分。也就是说,不能有两个具有相同名称和参数类型但返回类型不同的方法。

2.默认字段初始化

如果未在构造函数中显式设置字段,则会将其自动设置为默认值:数字设置为0,布尔值设置为false,对象引用设置为null。有人认为依靠默认值是不好的编程习惯。当然,如果对字段进行了不可见的初始化,这会使某人更难理解您的代码。

注意:这是字段和局部变量之间的重要区别。您必须始终在方法中显式初始化局部变量。但是在类中,如果不初始化字段,则会将其自动初始化为默认值(0,false或null)。

例如,考虑Employee类。假设您未指定如何初始化构造函数中的某些字段。默认情况下,salary字段将初始化为0,name和hireDay字段将初始化为null。

但是,这不是一个好主意。如果有人调用了getName或getHireDay方法,他们将得到他们可能不希望的空引用:

LocalDate h = harry.getHireDay();

int year = h.getYear(); // throws exception if h is null

3.不带参数的构造函数

许多类都包含一个不带参数的构造函数,该构造函数创建的对象的状态设置为适当的默认值。例如,这是Employee类的无参数构造函数:

public Employee()

{

name = "";

salary = 0;

hireDay = LocalDate.now();

}

如果您编写的类没有任何构造函数,那么将为您提供一个无参数的构造函数。此构造函数将 所有实例字段设置为其默认值。因此,实例字段中包含的所有数字数据将为0,所有布尔值将为false,所有对象变量将为null。

如果一个类至少提供一个构造函数,但不提供无参数构造函数,则在不提供参数的情况下构造对象是非法的。例如,清单4.2中的原始Employee类提供了一个构造函数:

public Employee(String n, double s, int year, int month, int day)

对于该类,构造默认Employee是不合法的。也就是说,调用e = new Employee();

会是一个错误。

注意:请记住,仅当您的类没有其他构造函数时,您才能获得无参数构造函数。如果您使用自己的单个构造函数编写类,并且希望类的用户能够通过调用以下内容来创建实例:

new ClassName()

那么您必须提供一个无参数的构造函数。当然,如果您对所有字段的默认值都满意,则只需提供:

public ClassName()

{

}

C ++注意: C ++使用“初始化列表”语法构造字段:

Employee :: Employee(String n,double s,int y,int m,int d)// C ++
: name(n),

salary(s),

hireDay(y, m, d)

{

}

4.显式字段初始化

通过重载类中的构造方法,您可以建立许多方法来设置类的实例字段的初始状态。确保无论构造函数调用如何,每个实例字段都设置为有意义的值,这始终是一个好主意。

您可以简单地将一个值分配给类定义中的任何字段。例如:

class Employee

{

private String name = "";

. . .

}

该分配是在构造函数执行之前执行的。如果类的所有构造函数都需要将特定的实例字段设置为相同的值,则此语法特别有用。

初始化值不必为常数。这是一个使用方法调用初始化字段的示例。考虑一个Employee类,其中每个雇员都有一个id字段。您可以按以下方式对其进行初始化:

class Employee

{

private static int nextId;

private int id = assignId();

. . .

private static int assignId()

{

int r = nextId;

nextId++;

return r;

}

. . .

}

5.调用另一个构造函数

关键字this表示方法的隐式参数。但是,此关键字具有第二个含义。

如果 构造函数的第一条语句的形式为this(. . .),则构造函数将调用同一类的另一个构造函数。这是一个典型示例:

public Employee(double s)

{

// calls Employee(String, double)

this("Employee #" + nextId, s);

nextId++;

}

当您调用new Employee(60000)时,Employee(double)构造函数将调用Employee(String,double)构造函数。

以这种方式使用this关键字很有用-您只需编写一次通用构造代码。

C ++注: Java中的this引用与C ++中的this指针相同。
但是,在C ++中,一个构造函数不可能调用另一个构造函数。

6.初始化块

您已经看到了两种初始化数据字段的方法:

•通过在构造函数中设置值

•通过在声明中分配值

Java中存在第三种机制,称为 初始化块。类声明可以包含任意代码块。每当构造该类的对象时,就会执行这些块。例如:

class Employee

{

private static int nextId;

private int id;

private String name;

private double salary;

// object initialization block

{

id = nextId;

nextId++;

}

public Employee(String n, double s)

{

name = n;

salary = s;

}

public Employee()

{

name = "";

salary = 0;

}

. . .

}

在此示例中,无论使用哪个构造函数构造对象,都在对象初始化块中初始化id字段。初始化块首先运行,然后执行构造函数的主体。

这种机制从没有必要,也不是普遍的。通常是更多可以将初始化代码直接放在构造函数中。

这是在调用构造函数时发生的详细情况:

1.如果构造函数的第一行调用了第二个构造函数,则第二个构造函数将使用提供的参数执行。

2.除此以外,
a)所有数据字段均被初始化为其默认值(0,false或null)。

b)所有字段初始化程序和初始化块都按照它们在类声明中出现的顺序执行。

3.构造函数的主体被执行。

要初始化静态字段,请提供初始值或使用静态初始化块。您已经看到了第一种机制:

private static int nextId = 1;

如果您的类的静态字段需要复杂的初始化代码,请使用静态初始化块。

将代码放在一个块中,并用关键字static对其进行标记。这是一个例子。我们希望员工ID号以小于10,000的随机整数开头:

static

{

var generator = new Random();

nextId = generator.nextInt(10000);

}

静态初始化是在首次加载该类时发生的。与实例字段一样,静态字段为0,false或null,除非您将其明确设置为另一个值。

所有静态字段初始化程序和静态初始化块均按照它们在类声明中出现的顺序执行。

清单4.5中的程序显示了我们在本节中讨论的许多功能:

•重载的构造函数

•使用this(...)调用另一个构造函数

•无参数构造函数

•对象初始化块

•静态初始化块

•实例字段初始化

import java.util.*;
public class ConstructorTest {
public static void main(String[] args){

Employee1 [] staff = new Employee1[3];

//以三种不同方式初始化对象
staff[0] = new Employee1("Harry",30000);
staff[1] = new Employee1(60000);
staff[2] = new Employee1();

for(Employee1 e:staff){
    System.out.println(e.getName()+" "+ e.getId()+" "+e.getSalary());
        }
    }
}  

class Employee1{
    private double salary;
    private static int nextId;
    private int Id;
    private String name =" "; //初始化为“ ”

//生成随机编号
    static
    {
        var generator = new Random();
        nextId = generator.nextInt(10000);
    }

    {
        Id = nextId;
        nextId++;
    }

    public Employee1(String n,double s){
        name = n;
        salary = s;
    }

    public Employee1(double s){
        this("Employee#"+nextId,s); //调用public Employee1(String n,double s)构造函数
    }
    public Employee1(){

    }
    public String getName(){
        return name;
    }
    public int getId(){
        return Id;
    }
    public double getSalary(){
        return salary;
    }
}
运行结果如下
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容