类的成员:属性、方法、构造器、代码块
代码块:
作用:为属性初始化
一、非静态代码块
1.语法格式:
【修饰符】 class 类名 【extends 父类】{
{
非静态代码块;
}
}
2.执行的特点
(1)在创建对象时自动执行,每创建一个对象就执行一次。如果有多个非静态代码块,按顺序依次执行。
(2)非静态代码块与属性的显式赋值,两者谁在前面谁就先执行。
(3)上述两者都是先于构造器执行。
(4)如果创建子类的对象,会先执行父类的“非静态代码块、父亲的属性的显式赋值、父类的构造器”
3.实例化初始化方法<init>(...)
(1).java代码编译为.class时,会把代码重新组装,如果类中有N个构造器,就会重新组为N个实例初始化方法。
无参构造-》<init>()
有参构造-》<init>(形参列表)
(2)每一个构造器对应一个实例初始化方法,实例初始化方法由三部分代码构成
(A)属性的显式赋值语句
(B)非静态代码块的语句
(C)构造器的语句
其中(A)(B)时按顺序组装,但是(C)无论位置在哪里,都在最后。
(3)创建子类对象时,会先调用父类的实例初始化方法,执行哪个父类的实例初始化方法,要看子类构造器调用的是哪个父类的构造器。
(4)注意方法的重写问题。
static:静态的
1.static是一个关键字,同时是一个修饰符。
2.static可以修饰什么?
(1)属性
(2)方法
(3)代码块
(4)内部类
3.static修饰属性
用static修饰的属性,称为静态变量、类变量
(1)值的存储位置不同
非静态的属性:堆
静态变量:方法区
(2)值的初始化(赋值)的时机不同
非静态的属性:创建实例对象时,在<init>()实例初始化方法中完成初始化。
静态变量:类初始化时,在<clinit>()类初始化方法中完成初始化。
推出:静态变量的初始化比非静态的属性要早。
(3)共享型不同
非静态的属性:每一个对象是独立的,各自存了一份。
静态变量:所有该类的对象共享同一份
(4)声明周期
非静态的属性:随着对象的创建而存在,当对象被垃圾回收器回收就消失。
静态变量:随着类的初始化二初始化,随着类的卸载而卸载。
静态变量的生命周期 = 类的生命周期
非静态的属性的生命周期 = 对象的生命周期,每一个对象的生命周期是独立的。
(5)get/set不同
非静态的属性:对应get/set也是非静态的,如果局部变量与属性重名了,用this.区别
静态变量:对应get/set也是静态的,如果局部变量与属性重名了,用类名.区别
4.static修饰方法
static修饰方法,称为静态方法,类方法
(1)可以通过“类名.”调用,可以不通过“对象.”调用,当然也可以通过“对象.”调用。
(2)静态方法中是不可以出现this,super这些关键字
(3)静态方法中是不可以直接使用本类中非静态的成员(属性、方法、内部类)
(4)静态方法不能被重写的。
5.static修饰代码块
(1)作用
代码块的作用:为属性初始化
代码块是分为非静态代码块和静态代码块
非静态代码块的作用:为非静态的属性初始化
静态代码块的作用:为静态的属性,静态变量初始化
(2)语法结构
【修饰符】 class 类名 【extends 父类】{
{
非静态代码块;
}
static{
静态代码块;
}
}
(3)执行的特点
A:无论创建几个对象,静态代码块只执行一次,如果有多个,那么就按顺序执行。
B:静态代码块优先于非静态代码块等执行
因为静态代码块的执行是在类初始化时执行,类初始化执行的是一个叫做<clinit>的类初始化方法。
类初始化的<clinit>()方法由如下两个部分组成:
第一:静态变量的显式赋值
第二:静态代码块
第一和第二谁在上面谁先执行,按顺序执行。
C:子类的初始化时,如果发现父类还没有初始化,会先初始化父类,即先执行父类的<clinit>()方法。
局部变量:栈