Java语言(5)【类&对象】-构造方法、初始化程序

一、类的构造方法

通过new关键字创建对象实例时,调用类的构造方法对 对象的内存 进行初始化。其工作过程是这样的:

(1)分配存储新建的对象实例的内存。

(2)调用构造方法,并传入指定的参数。

(3)构造方法使用这些参数执行初始化新对象所需的一切操作。

关于构造方法:

(1) 构造方法的名称始终和类名一样。

(2) 声明构造方法时不指定返回值类型,连 void 都不用

(3) 一个类可以有多个构造方法,每个构造方法参数不同。

默认构造方法:

每个类至少需要一个构造方法。

如果没有定义类时,没有显式定义构造方法,javac 编译器自动提供了一个构造方法(叫作默认构造方法)。这个构造方法:

(1)没有参数。

(2)不执行任何特殊的初始化操作。

此时:对象实例的变量需要通过增加代码显式初始化。如:

  Circle c = new Circle();

  c.r = 0.25;

多个构造方法之间的调用:

类定义中可能存在多个构造方法,这些构造方法可能共用大量的初始化代码。此时,可以通过this()进行构造方法的互相调用,来复用初始化代码。如:

  // 这是基本构造方法:携带一个入参,初始化半径

  public Circle(double r) { this.r = r; }

  // 这个构造方法使用this()调用前一个构造方法,采用默认半径1.0

  public Circle() { this(1.0); }

注:使用 this() 时有个重大的限制:只能出现在构造方法的第一个语句中。

二、类中字段的默认值,Java是如何实现初始化--自动生成初始化代码

在类定义中,字段可以指定默认值、或不指定默认值。如:

class A {

  int i = 0;

  float r;

}

1、对于没有指定默认值的字段,Java是如何赋值的呢?

     如果没有指定初始值,字段自动使用默认值初始化:false、 \u0000、0、0.0 或 null。具体使用哪个值,根据字段的类型而定。

2、如果定义时指定了字段的默认值,Java是如何实现赋值的呢?

  如:

 class Dog{

  final int legNum = 4;

       String name;

       public Dog(String name) {

    this.name = name;

  } 

 }

   通过new Dog("Tom");创建对象时,Java是如何实现把对象实例内存中的legNum字符赋值为4的呢?

   

   Java对类定义中指指定初始值的字段,会生成初始化代码。根据是实例字段、还是类字段,其工作方式有差异:

   (1)实例字段

  • java编译器会自动为 指定了初始值的字段  生成初始化代码,然后把这些代码放到类的所有构造函数中。          
  • 这些初始化代码 按照 字段在类中定义的顺序 插入到构造方法中。
  • 如果类存在多个构造方法,其中某个构造方法使用了this()方式调用了另外一个构造方法。那么java编译器不会把 初始化代码 插入到当前构造方法中,而是插入到this()对应的构造方法中。通过调用this()实现执行 初始化代码

       样例:如下,java编译器只会在第一个构造方法中 插入针对legNum字段的初始化代码。第二个、第三构造方法通过this()方式调用第一个构造方法实现legNum字段初始化代码的执行。

   class Dog{

    final int legNum = 4;

    int age;

         String name;

    

    public Doc(int age, String name) {

      this.age= age;

      this.name = name;

    }

         public Dog(String name) {

      this(2, name);

              }     

    public Dog() {

      this(2, "Tom");

              } 

   }

           加入的初始化代码后的构造函数为:

      public Doc(int age, String name) {

                      legNum = 4;

      this.age= age;

      this.name = name;

    }

     (2)类字段

  如果是类字段。在没有创建对象实例情况下,指定了初始值的类字段就是分配内存和赋值。java如何实现的呢?

       javac 会为每个类自动生成一个类初始化方法。类字段在这个方法的主体中初始化。这个方法只在首次使用类之前调用一次(经常是在 Java 虚拟机首次加载类时)。

  • 和实例字段的初始化一样,类字段的初始化表达式按照 类字段 在类定义中的的顺序插入 类初始化方法
  • 由于类字段初始化在 类初始化方法中是顺序的,所以,类字段的初始化表达式可以使用在其之前声明的类字段。
  • 类初始化方法是内部方法,对Java 程序员不可见。在类文件中,它的名称是 <clinit>。

三、Java也允许开发人员自己编写类中字段的 初始化代码,称之为“初始化程序

(1)针对类字段的 初始化程序 称之为 “静态初始化程序”

  “静态初始化程序”由 static 和 其后的 花括号+代码块 组成。(没有方法名)。样例:

  public class TrigCircle {

       // 这是静态查找表和各自的初始化程序

       private static final int NUMPTS = 500;

       private static double sines[] = new double[NUMPTS];

       private static double cosines[] = new double[NUMPTS];

 

      // 这是一个静态初始化程序,填充上述数组

       static {

           double x = 0.0;

           double delta_x = (Circle.PI/2)/(NUMPTS-1);

           for(int i = 0, x = 0.0; i < NUMPTS; i++, x += delta_x) {

               sines[i] = Math.sin(x);

               cosines[i] = Math.cos(x);

           }

      }

       ……

  }

  • 在类定义中,静态初始化程序可以放在字段和方法定义能出现的任何位置。  
  • 一个类可以有任意多个静态初始化程序。
  • 静态初始化程序 的主体会和所有静态字段的 初始化代码 一起合并到类初始化方法中。
  • 静态初始化程序 不能使用this关键字

(2)针对实例字段的 初始化程序 称之为 “实例初始化程序”

  “静态初始化程序”由  花括号+代码块 组成。(没有方法名)。样例:

  public class TrigCircle {

       private static final int NUMPTS = 100;

       private int[] data = new int[NUMPTS];

      // 这是一个实例初始化程序,填充上述数组     

     {

       for(int i = 0; i < NUMPTS; i++)

                 data[i] = i;

     }

       ……

  }

  • 在类定义中,实例初始化程序可以放在字段和方法定义能出现的任何位置。  
  • 一个类可以有任意多个实例初始化程序。
  • 实例初始化程序 的主体会和所有实例字段的 初始化代码 一起合并到类的 构造方法 的开头。
  • 不过,实际开发中很少使用 实例初始化程序 。

猜你喜欢

转载自www.cnblogs.com/yickel/p/12770533.html