1.重载

  有些类有多个构造器。例如,可以如下构造一个空的StringBuilder对象:

StringBuilder message = new StringBuilder();

  或者,可以指定一个初始字符串:

StringBuilder message = new StringBuilder("Hello World!");

  这种特征叫做重载(overloading)。如果多个方法(比如,StringBuilder构造器方法)有相同的名字、不同的参数,便产生了重载。编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与特定方法调用所使用的值类型进行匹配来挑选出相应的方法。如果编译器找不到匹配的参数,就会产生编译时错误,因为根本不存在匹配,或者没有一个比其他更好(这个过程被称为重载解析(overloading resolution))。值得注意的是,Java允许重载任何方法,而不只是构造器方法。

2.默认域初始化

  如果在构造器中没有显式的给域赋予初值,那么就会被自动的赋予为默认值:数值为0、布尔值为false、对象应用为null。然而,只有缺少程序设计经验的人才会这么做。确实,如果不明确的对域进行初始化,就会影响程序代码的可读性。就比如说上篇的Employee类,假定没有在构造器中对某些域进行初始化,就会默认的将name和sex域初始化为null,将age域初始化为0。但是这不是一个良好的编程习惯。如果此时,我们调用getName方法或者getSex方法,将会得到一个null值的引用,这应该不是我们所希望的结果。

3.无参构造器

  很多类都包含一个无参的构造函数,对象由无参构造函数创建时,其状态会设置为适当的默认值。如果编写一个类时没有编写构造器,那么系统就会提供一个无参的构造器。这个构造器将所有的实力域设置为默认值。

  注意:如果类中提供了至少一个构造器,但是没有提供无参数的构造器,则在构造对象时如果没有提供参数就会被视为不合法。例如Employee类只提供了一个构造方法:

package jackWe;

public class Employee {
private String name;
private int age;
private String sex; public Employee(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public void getOneHeight() {
System.out.println("姓名:"+ this.name + ";");
System.out.println("年龄:"+ this.age + ";");
System.out.println("性别:"+ this.sex + ";");
System.out.println("身高:"+ (int)(Math.random() * 200) + "cm。");
}
}

  对于这个类,构造默认的雇员就会是不合法的。也就是,调用

Employee employee = new Employee(); // 创建将会产生错误

  将会产生错误。

  警告:请记住,仅当类没有提供任何构造器的时候,系统才会提供一个默认的构造器。如果在编写类的时候,给出了一个构造器,哪怕是很简单的,要想让这个类的用户能够按照下列方式构造实例:

  new  className()

  就必须提供一个默认的构造器(即不带参数的构造器)。当然,如果希望所有域被赋予默认值,可以采用下列格式:

public Employee() {
// 默认构造器
}

4.调用另一个构造器

  关键字this引用方法的隐式参数。然而,这个关键字还有另外一个含义。如果构造器的第一个语句如同this(...),那么,这个构造器将调用同一类中的另外一个构造器,下面给个例子:

public Employee() {
this("Jack",18,"男"); //调用另外一个构造器
}

5.初始化块

  前面已经说过了两种初始化数据域的方法:

  ①、构造器中设置值;

  ②、在声明中赋值。

  实际上,Java还有第三种机制,成为初始化块。在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行。

  由于初始化数据域有多种途径,所以列出构造过程的所有路径可能相当混乱。下面是调用构造器的具体处理步骤:

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

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

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

  ④、执行这个构造器的主体。

  当然,我们应该精心的组织好初始化代码,这样有利于其他程序员的理解。例如,如果让类构造器行为依赖于数据域声明的顺序,那就会显得很奇怪并且容易引起错误。

  可以通过提供一个初始化值,或者使用一个静态的初始化块来对静态域进行初始化:

private static int nextId = 1;

  如果对类的静态域进行初始化的代码比较复杂,那么可以使用静态的初始化块。

  将代码放在一个块中,并标记关键字 static 。例如:

// static initialization block
static {
Employee employee = new Employee();
int age = (int) (Math.random() * 100);
employee.setAge(age);
}

  在类第一次加载的时候,将会进行静态域的初始化。与实力域不一样,除非将它们显式的设置成其他值,否则默认的初始值为0、false或null。所有的静态初始化语句以及静态初始化块都将依照类定义的顺序执行。

6.对象析构域finalize方法

  由于Java有自动的垃圾回收器,不需要人工回收内存,所以Java不支持析构器。当然,某些对象使用了内存之外的其他资源,例如,文件或使用了系统资源的另一个对象的句柄。在这种情况下,当资源不在需要时,将其回收再利用将显得十分重要。

  可以为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象之前调用。在实际应用中,不要依赖于使用finalize方法回收任何短缺的资源,这是因为很难知道这个方法什么时候才能够调用。

  如果某个资源需要在使用完毕后立刻被关闭,那么就需要人工来管理。对象用完时,可以应用一个close方法来完成相应的清理操作。

Java基础—对象构造的更多相关文章

  1. 《java基础——对象的拷贝》

    java基础--对象的拷贝 一.浅拷贝: 规则: 1. 浅拷贝只是拷贝了源对象的地址,所以源对象的值发生变化时,拷贝对象的值也会发生变化. 2. 浅拷贝相当于两个对象共用一套实例. 格式: 类名 对象 ...

  2. Java中对象构造

    构造函数 作用:在构造对象的同时初始化对象.java强制要求对象 诞生同时被初始化,保证数据安全. 调用过程和机制:①申请内存,②执行构造函数的函数体,③返回对象的引用. 特点:与类同名,无返回类型, ...

  3. Java基础-对象与类

    面向对象程序设计概述 面向对象的程序设计(简称OOP)时当今主流的程序设计范型,已经取代了"结构化"过程化程序设计开发技术,Java是完全面向对象的. 类 类设计构造对象的模板或蓝 ...

  4. Java基础--对象的克隆

    文章转载自https://www.cnblogs.com/Qian123/p/5710533.html 阅读目录 为什么要克隆? 如何实现克隆 浅克隆和深克隆 解决多层克隆问题 总结 假如说你想复制一 ...

  5. Java之对象构造过程

    先来运行一段代码 class A { public A() { init(); } public void init() { } public static void main(String[] ar ...

  6. java基础-对象的初始化

    一 前言 本节内容将会提到方法重载,对象的初始化,对象的构造器,和this关键字的使用,以及会简要的概括一下java中对象回收机制.觉得文章不错的读者可以关注一下作者的博客和公众号(同博客名称) 二 ...

  7. 一天一个Java基础——对象和类

    1.在Java中你所做的全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象 2.可以在类中设置两种类型的元素:字段(也被称作数据成员)和方法(也被称作成员函数) 3.字段可以是任何类型的对象 ...

  8. Java基础——对象容器(顺序、集合、Hash)

    扩展: For-each循环 for (String s: str) { System.out.println(s); } 等同于for (int i = 0; i < str.length; ...

  9. Java基础-对象的内存分配与初始化(一定要明白的干货)

    首先,什么是类的加载?类的加载由类加载器执行.该步骤将查找字节码(classpath指定目录),并从这些字节码中创建一个Class对象.Java虚拟机为每种类型管理一个独一无二的Class对象.也就是 ...

随机推荐

  1. Azure Web App (二)使用部署槽切换部署环境

    一,引言 前天我们将到使用Azure的 Pass 服务 “Web App” 去部署我们的.NET Core Web项目,也同时有介绍到如何在VS中配置登陆中国区的Azure账号,今天接着讲,我们部署完 ...

  2. jmeter 及测试(转载)

    负载测试:在一定的工作负荷下,给系统造成的负荷及系统响应的时间. 压力测试:在一定的负荷条件下,长时间连续运行系统给系统性能造成的影响.   1.性能测试(Performance Test):通常收集 ...

  3. 手写SpringBoot自动配置及自定义注解搭配Aop,实现升级版@Value()功能

    背景 项目中为了统一管理项目的配置,比如接口地址,操作类别等信息,需要一个统一的配置管理中心,类似nacos. 我根据项目的需求写了一套分布式配置中心,测试无误后,改为单体应用并耦合到项目中.项目中使 ...

  4. 入门大数据---Hive计算引擎Tez简介和使用

    一.前言 Hive默认计算引擎时MR,为了提高计算速度,我们可以改为Tez引擎.至于为什么提高了计算速度,可以参考下图: 用Hive直接编写MR程序,假设有四个有依赖关系的MR作业,上图中,绿色是Re ...

  5. Fisher算法+两类问题

    文章目录 一.Fisher算法 二.蠓的分类问题: 三.代码实现: 一.Fisher算法 二.蠓的分类问题: 两种蠓Af和Apf已由生物学家根据它们的触角和翼长加以区分(Af是能传播花粉的益虫,Apf ...

  6. Shell基本语法---处理海量数据的grep命令

    grep命令 shell脚本三剑客之一 grep应用场景:通常对数据进行 行的提取 语法:grep [选项] [内容] [file] -v 对内容进行取反提取 -n 对提取的内容显示行号 -w 精确匹 ...

  7. [redis] -- 集群篇

    三种集群方式 主从同步:主从复制模式中包含一个主数据库实例(master)与一个或多个从数据库实例(slave) 优点: master能自动将数据同步到slave,可以进行读写分离,分担master的 ...

  8. 题解 洛谷 P4694 【[PA2013]Raper】

    首先考虑题目的性质,不难发现光盘的花费是一个凸函数.当生产 \(0\) 张光盘时,其花费为 \(0\),随着光盘生产数的增加,最优情况肯定是先选择工厂便宜的时刻,所以花费会增长越来越快,因此其为一个下 ...

  9. 分布式锁(2) ----- 基于redis的分布式锁

    分布式锁系列文章 分布式锁(1) ----- 介绍和基于数据库的分布式锁 分布式锁(2) ----- 基于redis的分布式锁 分布式锁(3) ----- 基于zookeeper的分布式锁 代码:ht ...

  10. SpringBoot + Spring Cloud Consul 服务注册和发现

    什么是Consul Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其它分布式服务注册与发现的方案,Consul 的方案更"一站式" ...