Java 构造函数

Java 构造函数,在初始化对象的时候,前面我们都是直接对每个变量赋值,有一个更简单的方式对实例变量赋初值,就是构造方法,我们先看下代码。在Point类定义中增加如下代码:

public Point(){
    this(0,0);
}
public Point(int x, int y){
      this.x = x;
      this.y = y;
  }

这两个就是构造方法,构造方法可以有多个。不同于一般方法,构造方法有一些特殊的地方:

  • 名称是固定的,与类名相同。这也容易理解,靠这个用户和Java系统就都能容易地知道哪些是构造方法。
  • 没有返回值,也不能有返回值。构造方法隐含的返回值就是实例本身。

与普通方法一样,构造方法也可以重载。第二个构造方法是比较容易理解的,使用this对实例变量赋值。
我们解释下第一个构造方法,this(0,0)的意思是调用第二个构造方法,并传递参数“0,0”,我们前面解释说this表示当前实例,可以通过this访问实例变量,这是this的第二个用法,用于在构造方法中调用其他构造方法。

这个this调用必须放在第一行,这个规定也是为了避免误操作。构造方法是用于初始化对象的,如果要调用别的构造方法,先调别的,然后根据情况自己再做调整,而如果自己先初始化了一部分,再调别的,自己的修改可能就被覆盖了。

这个例子中,不带参数的构造方法通过this(0,0)又调用了第二个构造方法,这个调用是多余的,因为x和y的默认值就是0,不需要再单独赋值,我们这里主要是演示其语法。

我们来看下如何使用构造方法,代码如下:

Point p = new Point(2,3);

这个调用就可以将实例变量x和y的值设为2和3。前面我们介绍new Point()的时候说,它至少做了两件事,一件是分配内存,另一件是给实例变量设置默认值,这里我们需要加上一件事,就是调用构造方法。调用构造方法是new操作的一部分。

通过构造方法,可以更为简洁地对实例变量进行赋值。关于构造方法,下面我们讨论两个细节概念:一个是默认构造方法;另一个是私有构造方法。

1.默认构造方法
每个类都至少要有一个构造方法,在通过new创建对象的过程中会被调用。但构造方法如果没什么操作要做,可以省略。Java编译器会自动生成一个默认构造方法,也没有具体操作。但一旦定义了构造方法,Java就不会再自动生成默认的,具体什么意思呢?在这个例子中,如果我们只定义了第二个构造方法(带参数的),则下面语句:

Point p = new Point();

就会报错,因为找不到不带参数的构造方法。

为什么Java有时候自动生成,有时候不生成呢?在没有定义任何构造方法的时候,Java认为用户不需要,所以就生成一个空的以被new过程调用;定义了构造方法的时候,Java认为用户知道自己在干什么,认为用户是有意不想要不带参数的构造方法,所以不会自动生成。

2.私有构造方法
构造方法可以是私有方法,即修饰符可以为private,为什么需要私有构造方法呢?大致可能有这么几种场景:

  • 不能创建类的实例,类只能被静态访问,如Math和Arrays类,它们的构造方法就是私有的。
  • 能创建类的实例,但只能被类的静态方法调用。有一种常见的场景:类的对象有但是只能有一个,即单例(单个实例)。在这种场景中,对象是通过静态方法获取的,而静态方法调用私有构造方法创建一个对象,如果对象已经创建过了,就重用这个对象。
  • 只是用来被其他多个构造方法调用,用于减少重复代码。

类和对象的生命周期

了解了类和对象的定义与使用,下面我们再从程序运行的角度理解下类和对象的生命周期。

在程序运行的时候,当第一次通过new创建一个类的对象时,或者直接通过类名访问类变量和类方法时,Java会将类加载进内存,为这个类分配一块空间,这个空间会包括类的定义、它的变量和方法信息,同时还有类的静态变量,并对静态变量赋初始值。

类加载进内存后,一般不会释放,直到程序结束。一般情况下,类只会加载一次,所以静态变量在内存中只有一份。

当通过new创建一个对象的时候,对象产生,在内存中,会存储这个对象的实例变量值,每做new操作一次,就会产生一个对象,就会有一份独立的实例变量。

每个对象除了保存实例变量的值外,可以理解为还保存着对应类型即类的地址,这样,通过对象能知道它的类,访问到类的变量和方法代码。

实例方法可以理解为一个静态方法,只是多了一个参数this。通过对象调用方法,可以理解为就是调用这个静态方法,并将对象作为参数传给this。

对象的释放是被Java用垃圾回收机制管理的,大部分情况下,我们不用太操心,当对象不再被使用的时候会被自动释放。

具体来说,对象和数组一样,有两块内存,保存地址的部分分配在栈中,而保存实际内容的部分分配在堆中。栈中的内存是自动管理的,函数调用入栈就会分配,而出栈就会释放。

堆中的内存是被垃圾回收机制管理的,当没有活跃变量指向对象的时候,对应的堆空间就可能被释放,具体释放时间是Java虚拟机自己决定的。活跃变量就是已加载的类的类变量,以及栈中所有的变量。

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!