欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

[ Java学习基础 ] Java构造函数

程序员文章站 2022-07-09 14:23:13
构造方法是类中特殊方法,用来初始化类的实例变量,它在创建对象(new运算符)之后自动调用。 Java构造方法的特点如下: 构造方法名必须与类名相同。 构造方法没有任何返回值,包括void。 构造方法只能与new运算符结合使用。 示例代码如下: 代码第15行是声明了一个构造方法,其中有两个参数w和h, ......

     构造方法是类中特殊方法,用来初始化类的实例变量,它在创建对象(new运算符)之后自动调用。

Java构造方法的特点如下:

  1. 构造方法名必须与类名相同。

  2. 构造方法没有任何返回值,包括void。

  3. 构造方法只能与new运算符结合使用。

示例代码如下:

 1 //Rectangle.java文件
 2 package com.a51work6;
 3 
 4 // 矩形类
 5 public class Rectangle {
 6 
 7     // 矩形宽度
 8     int width;
 9     // 矩形高度
10     int height;
11     // 矩形面积
12     int area;
13 
14     // 构造方法
15     public Rectangle(int w, int h) {        
16         width = w;
17         height = h;
18         area = getArea(w, h);
19     }
20     ...
21 }

代码第15行是声明了一个构造方法,其中有两个参数w和h,用来初始化Rectangle对象的两个成员变量width和height,注意前面没有任何的返回值。

默认构造方法

有时在类中根本看不到任何的构造方法。例如本节中User类代码如下:

 1 //User.java文件
 2 package com.a51work6;
 3 
 4 public class User {
 5 
 6     // 用户名
 7     private String username;
 8 
 9     // 用户密码
10     private String password;
11 
12 }

从上述User类代码,只有两个成员变量,看不到任何的构造方法,但是还是可以调用无参数的构造方法创建User对象,因为Java虚拟机会为没有构造方法的类,提供一个无参数的默认构造方法,默认构造方法其方法体内无任何语句,默认构造方法相当于如下代码:

//默认构造方法
public User() {
}

默认构造方法的方法体内无任何语句,也就不能够初始化成员变量了,那么这些成员变量就会使用默认值,成员变量默认值是与数据类型有关。

构造方法重载

      在一个类中可以有多个构造方法,它们具体有相同的名字(与类名相同),参数列表不同,所以它们之间一定是重载关系。

构造方法重载示例代码如下:

 1 //Person.java文件
 2 package com.a51work6;
 3 
 4 import java.util.Date;
 5 
 6 public class Person {
 7 
 8     // 名字
 9     private String name;
10     // 年龄
11     private int age;
12     // 出生日期
13     private Date birthDate;
14 
15     public Person(String n, int a, Date d) {        
16         name = n;
17         age = a;
18         birthDate = d;
19     }
20 
21     public Person(String n, int a) {                
22         name = n;
23         age = a;
24     }
25 
26     public Person(String n, Date d) {               
27         name = n;
28         age = 30;
29         birthDate = d;
30     }
31 
32     public Person(String n) {                       
33         name = n;
34         age = 30;
35     }
36 
37     public String getInfo() {
38         StringBuilder sb = new StringBuilder();
39         sb.append("名字: ").append(name).append('\n');
40         sb.append("年龄: ").append(age).append('\n');
41         sb.append("出生日期: ").append(birthDate).append('\n');
42         return  sb.toString();
43     }
44 }

上述代码Person类代码提供了4个重载的构造方法,如果有准确的姓名、年龄和出生日期信息,则可以选用代码第15行的构造方法创建Person对象;如果只有姓名和年龄信息则可选用代码第21行的构造方法创建Person对象;如果只有姓名和出生日期信息则可选用代码第26行的构造方法创建Person对象;如果只有姓名信息则可选用代码第32行的构造方法创建Person对象。

Tips:如果在类中添加了带参的构造函数,系统就不会在自动生成无参的构造函数,所以建议添加带参数的构造函数后,再手动添加一个默认无参的构造函数。

构造方法封装

构造方法也可以进行封装,访问级别与普通方法一样,构造方法的访问级别参考[ Java学习基础 ] Java的封装性与访问控制中图所示。示例代码如下:

 1 //Person.java文件
 2 package com.a51work6;
 3 
 4 import java.util.Date;
 5 
 6 public class Person {
 7 
 8     // 名字
 9     private String name;
10     // 年龄
11     private int age;
12     // 出生日期
13     private Date birthDate;
14 
15     // 公有级别限制
16     public Person(String n, int a, Date d) {        
17         name = n;
18         age = a;
19         birthDate = d;
20     }
21 
22     // 默认级别限制
23     Person(String n, int a) {                       
24         name = n;
25         age = a;
26     }
27 
28     // 保护级别限制
29     protected Person(String n, Date d) {            
30         name = n;
31         age = 30;
32         birthDate = d;
33     }
34 
35     // 私有级别限制
36     private Person(String n) {                      
37         name = n;
38         age = 30;
39     }
40 
41     ...
42 }

上述代码第16行是声明公有级别的构造方法。代码第23行是声明默认级别,默认级别只能在同一个包中访问。代码第29行是保护级别的构造方法,该构造方法在同一包中与默认级别相同,在不同包中可以被子类继承。代码第36行是私有级别构造方法,该构造方法只能在当前类中使用,不允许在外边访问,私有构造方法可以应用于单例设计模式等设计。

----------------------------------------------------------------------------

初始化块和构造函数的执行顺序

读者可先自行阅读下面代码,判断输出结果:

 1   class B extends Object
 2   {
 3       static
 4       {
 5           System.out.println("Load B");    
 6       }
 7       public B()
 8       {
 9             System.out.println("Create B");      
10      }
11  }    
12  class A extends B
13  {
14      static
15      {
16          System.out.println("Load A");
17      }
18      public A()
19      {
20          System.out.println("Create A");
21      }
22  }
23  
24  public class Testclass
25  {
26      public static void main(String [] args)
27      {
28          new A();
29      }
30  }

输出结果:

Load B
Load A
Create B
Create A

      初始化块在构造器执行之前执行,类初始化阶段先执行最顶层父类的静态初始化块,依次向下执行,最后执行当前类的静态初始化块;创建对象时,先调调用顶层父类的构造方法,依次向下执行,最后调用本类的构造方法 。所以执行顺序为:父类静态代码 -> 子类静态代码块 -> 父类构造代码块 -> 父类构造函数 -> 子类构造代码块 -> 子类构造函数