关于对象构造的一些认识。

默认域初始化

如果在构造器中没有显示地给域赋予初值,那么就会被自动地赋予默认值:数值为0,布尔值为false,对象引用为null。然而,这显然是不安全的,在一个null引用上调用方法结果是不可预期的。

class Employee{
private String name;
private double salary;
}

无参数构造器

每个类都包含一个无参数构造函数,对象由无参数构造函数创建时,其状态会设置为适当的默认值。如果程序没有编写构造器,则这个构造器会将所有实例域设置为默认值:数值为0,布尔值为false,对象引用为null。

如果类中提供了至少一个构造器,但是没有提供无参数构造器,那么在构造对象时没有提供参数将视为不合法。也就是说:仅当类没有提供任何构造器时,系统才会提供一个默认的构造器。

class Employee{
private String name;
private double salary;
public Employee(){  //相当于系统提供的默认构造函数
this.name = null;
this.salary = 0;
}
}

显示域初始化

显示地设置类的实例域的初始状态,确保不管调用任何构造器,每个实例域都可以设置为一个有意义的值,这是一种良好的设计习惯。

class Employee{
private String name="张三";
private double salary=30000;
public Employee(){  
   this.name = "张三";
   this.salary = "30000"  
}

构造器方法重载

如果多个方法有相同的名字,不同的参数,便产生了重载。构造器方法也支持重载。编译器通过用各个方法给出的参数类型和特定方法调用所使用值的类型进行匹配来执行相应的方法。若无匹配则会产生编译错误。

class Employee{
private String name;
private double salary;
public Employee(){  //构造器一
  this.name = "张三";
    this.salary = "30000"  
}
public Employee(string name){  //构造器二  
this.name = name;
this.salary = "20000";
}
}

调用另一个构造器

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

class Employee{
private String name;
private double salary;
public Employee(double salary){  //构造器一
this("李四",salary);  //将调用构造器二 
}
public Employee(String name,double salary){  //构造器二
this.name = name;
this.salary = "20000";
}
}

初始化块和初始化语句

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

class Employee{
private String name="李四"; //初始化语句
private double salary; 
  { //初始化块
salary = "10000";
}
public Employee(){
this.name = "张三";
  this.salary = "30000"  
}
}

调用构造器的具体步骤

1)所有数据域被初始化为默认值

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

3)如果被调用的构造器第一行调用了另一个构造器,则执行那个构造器主体。

4)执行这个构造器主体。

实例:

 1 import java.util.Random;
2
3
4 public class ConstructorTest{
5 public static void main(String[] args){
6 Employee[] staff = new Employee[3];
7
8 staff[0] = new Employee("Harry",40000);//调用构造器一
9 System.out.println("name=" + staff[0].getName() +",id=" + staff[0].getId() + ",salary=" + staff[0].getSalary());
10 staff[1] = new Employee(60000);//调用构造器二
11 System.out.println("name=" + staff[1].getName() +",id=" + staff[1].getId() + ",salary=" + staff[1].getSalary());
12 staff[2] = new Employee();//调用构造器三,与不提供构造器时系统的默认构造器相同
13 System.out.println("name=" + staff[2].getName() +",id=" + staff[2].getId() + ",salary=" + staff[2].getSalary());
14 }
15 }
16
17
18 class Employee {
19 private static int nextID;
20 private int id;
21 private String name="";//初始化语句
22 private double salary;
23
24 static { //静态初始化块
25 System.out.println("静态块初始化");
26 Random generator = new Random();
27 nextID = generator.nextInt(10000);
28 }
29 { //初始化块
30 System.out.println("普通初始化块");
31 id = nextID;
32 nextID++;
33 }
34
35 public Employee(String name,double salary){//构造器一
36 this.name = name;
37 this.salary = salary;
38 }
39
40 public Employee(double salary){//构造器二
41 this("Emploee #" + nextID, salary);
42 }
43
44 public Employee(){//构造器三
45
46 }
47
48 public String getName() {
49 return name;
50 }
51
52 public double getSalary() {
53 return salary;
54 }
55
56 public int getId() {
57 return id;
58 }
59 }

运行结果:

静态块初始化
普通初始化块
name=Harry,id=5376,salary=40000.0
普通初始化块
name=Emploee #5377,id=5377,salary=60000.0
普通初始化块
name=,id=5378,salary=0.0

静态块只运行了一次的原因时因为静态块在类加载时运行的,而不是在创建对象时运行的。在程序的整个生命期值也只运行一次。详情可看java类加载过程。

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

  1. Java基础(一)对象构造

    由于Java对象构造非常重要,所以Java提供了多种编写构造器的机制. 1.重载 如果多个方法有相同的名字.不同的参数,便产生了重载.编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与 ...

  2. Java中对象构造

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

  3. Java内存结构、类的初始化、及对象构造过程

    概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的 ...

  4. Java对象的强、软、弱和虚引用原理+结合ReferenceQueue对象构造Java对象的高速缓存器

    //转 http://blog.csdn.net/lyfi01/article/details/6415726 1.Java对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变 ...

  5. Java之对象构造过程

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

  6. 零基础学Java(14)对象构造

    对象构造 之前学习了编写简单的构造器,可以定义对象的初始状态.但是,由于对象构造非常重要,所以Java提供了多种编写构造器的机制. 重载 有些类有多个构造器.例如,可以如下构造一个空的StringBu ...

  7. XML解析---利用XStream解析xml数据及反构造Java对象

    XStream 是一个轻量级的.简单易用的开放源代码 Java库,用于将 Java 对象序列化为 XML 或者再转换回来.而且XStream还能将java对象转成其它格式,比如JSon. 需要用到的包 ...

  8. Java对象序列化剖析

    对象序列化的目的 1)希望将Java对象持久化在文件中 2)将Java对象用于网络传输 实现方式 如果希望一个类的对象可以被序列化/反序列化,那该类必须实现java.io.Serializable接口 ...

  9. json相关类库,java对象与json相互转换

    有效选择七个关于Java的JSON开源类库 转自:http://www.open-open.com/lib/view/open1397870197828.html 翻译: (英语原文:http://w ...

随机推荐

  1. C#---OleDbHelper

    /// <summary> /// OleDbServer数据访问帮助类 /// </summary> public sealed class OleDbHelper { pu ...

  2. 使用TypeConverter类

    3.2.2 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射注意本小节的例子对于初学者来说理解起来比较困难而且实用性不大,主要是为喜欢刨根问底的WPF ...

  3. C++ Opencv图像直方图

    Mat image = imread("D:/ju.jpg"); imshow("素材图", image); int bins = 256; //直条为256 ...

  4. sizeof()和 strlen()的区别 --- 个人笔记

    在学习C语言和linux的时候,遇到了一些常见问题.题目,有些很简单,有些容易出错,本人水平有限,未免会出错,今天有时间,就将以前做的笔记,一一拿出来,写写blog. sizeof()和 strlen ...

  5. gradle依赖冲突

    # 如何定位依赖冲突? 了解如何定位依赖冲突问题之前,我们先手动制造一个依赖冲突. 我们在 build.gradle 引入两个依赖库: compile 'org.hibernate:hibernate ...

  6. java 捕获组与非捕获组

    非捕获组:格式:(?:xxxx), 如:(?:aaa)\\w+(bbb)\\1,\\1 代表重复捕获的第一组即是(bbb) public static void main(String[] args) ...

  7. 修改python import模块中的变量

    可以直接通过 模块名.变量名=xx 的方式修改模块中的全局变量,测试代码如下 模块:test_model.py x = 111 def inc_x(): global x x = x + 1 测试脚本 ...

  8. MySQL-SQL基础-查询1

    #子查询-某些情况下,当进行查询的时候,需要的条件是另外一个select语句的结果,这个时候就要用到子查询.用于子查询的关键字主要包括: in.not in.=.!=.exists.not exist ...

  9. NX二次开发-使用NXOPEN C++向导模板做二次开发

    版本 NX9+VS2012 1.怎么往VS软件里添加VC,C#,VB向导模板 先到NX安装目录下UGOPEN文件夹里找到这三个文件夹 拷贝到VS的安装目录下 这里有几个注意事项,VS2017,VS20 ...

  10. 安全强化机制——SELinux

    1.基本 SELINUX 安全性概念 SELINUX(Security Enhanced Linux),意思是安全增强型Linux, 是可保护你系统安全性的额外机制 在某种程度上 , 它可以被看作是与 ...