一、构造方法:
创建一个对象时,在许多时候都需要对属性进行一些初始化,或许可以自己写一个方法进行初始化,在创建对象后使用之后进行调用。但并不能百分之百保证不会忘记调用初始化方法,并且这样每次都要去调用也是繁琐的。
java为提供了一个在创建对象时由编译器自动去调用的构造方法。可以在构造方法中执行需要的初始化操作。
1、定义:
构造方法与类名相同且不带任何放回值。
class Test {
Test() {
System.out.println("Test");
}
}
- 在创建该类的对象时,类的构造器方法就会被自动调用。
- 构造方法和普通方法一样可以接受参数,在创建类的对象时必须按照构造方法的参数列表传入相应的参数。
- 构造方法可以重载,从而以不同的方式来创建一个类。
- 构造器本身没有任何返回值。因为如果构造器含有返回值,我们和编译器都不知道该任何去处理该值。
- 可以使用this关键字调用其他构造方法,但这样的调用只能出现在构造方法中,并且在最开始和一个方法中只能调用一次(只可使用this调用其他构造方法,不可使用类名调用)。
2、默认构造方法:
如果我们没有为类定义任何的构造器方法,那么编译器会为我们添加一个默认的构造方法,该构造方法没有参数和方法体。并在创建类时被自动调用。
如果我们为类定义了构造方法那么编译器就不会在创建默认的构造方法。
二、类成员变量初始化:
java确保所有属性在使用之前都被初始化。
1、 默认值
只是声明成员变量而未使用=号赋值时,成员变量都将获得一个默认值
- 基本类型初始化为0(char初始化为0,打印出来是空白)
- 引用类型初始化为null
2、 在定义成员变量的同时赋值:
class Test {
int i = 11;
long l = 100L;
char c = 'a';
float f = 1.1;
Date date = new Date();
}
可以在定义时使用方法来初始化:
class Test {
int a = 5;
int b = initB(a);
int initB(int x) {
return x * 10;
}
}
使用方法进行初始化时,如果方法带有参数必须保证传入的参数被初始化过。形参可以是初始化过得成员变量。
可以初始化化子句进行初始化:
class Test {
int a;
int b;
{
a = 10;
b = 12;
System.out.println(a + b)
}
}
初始化子句中可以出现任意代码,会在每次实例化类时在构造函数之前得到调用
3、使用构造器来初始化:
可以在构造函数中进行初始化,这样每次实例化类时构造函数中的初始化都会得到进行。但自动初始化依然会进行,它将在构造函数调用之前发生。
4、初始化顺序:
类的内部根据成员变量定义的顺序进行初始化。即使变量定义散布于方法定义之间,仍旧会在方法调用之前得到初始化。
三、静态成员变量的初始化
静态变量只能为成员变量,不能为方法中的局部变量,因为静态变量对类的所有对象只有一份。
如果没有对他进行显示的初始化,那么他默认值同标准初始化一样为0和null。如果在定义处进行初始化,那么他采用的方法与非静态数据没有什么区别。
静态变量只在类的clas对象被首次加载时初始化一次,以后就不在进行初始化。
静态成员变量在非静态成员变量之前进行初始化。
方法中的变量java不会提供初始值,而是在编译时发现为初始化直接使用的错误来保证。java不为方法中的变量提供默认值,因为提供了默认值可能在不应为默认值得情况下直接使用了默认值,反而掩盖了这种失误。因此在方法中强制进行初始化,往往可以避免这类错误。
4、静态子句:
静态子句可以将多个静态初始化组织在一起
class Test {
static Date date1;
static Date date2;
static {
date1 = new Date();
date2 = new Date();
}
}
静态子句中可以使用任意代码,不过它同样只在类clss被加载时执行一次。静态子执行顺序同其他静态变量一起按定义顺序进行初始化。
在使用引用之前初始化:
- 在定义对象的地方,能够在构造器调用之前被初始化
- 在类构造器中
- 使用对象之前,称为惰性初始化。在生成对象之前不值得及不必要每次都生成对象的情况下,这种方式可以减少额外的负担。
- 使用实例初始化
finalize()方法:
java的垃圾回收器只会释放由new分配的内存,对一些‘特殊’的内存区域并不会去释放,同时也有一些特殊地方出内存回收外还需要一些其他操作,这些特殊的区域就需要自己进行释放和操作,也就是说在不需要某个对象时执行一些特殊操作。
java没有提供析构函数的概念,所以这些操作必须自己进行。
类中定义finalize()方法,改方法将在垃圾回收器准备释放该对象时调用。当finalize方法并不一定会被调用,如果程序执行期间内存一直不紧张,那么垃圾回收机制就不会被触发,自然finalize方法也不会被调用。
对于一些很隐晦的清理,或许不敢保证他一定被清理时可以使用java提供的finalize()方法进行检查,发现这可能恢复漏了的操作,然后改进。但不能依赖finalize方法去做清理操作,毕竟改方法并不一定执行。
类的加载:
类的加载发生在创建第一个对象之时,但方位static成员的时候也会发生加载
在类被加载时执行执行静态成员变量的初始化,如果类有基类则先进行基类的静态成员初始化然后在执行本类的静态成员初始化,其中静态成员变量只在类加载时初始化一次以后不再初始化。当创建类的一个对象时如果该类有基类则先初始化基类的非静态成员然后调用基类的构造方法,然后才初始化该类的成员并调用该类的构造函数.
调用类的编译期常量并不会对类进行初始化。