关键字:static
1,static可以用来修饰什么
成员:属性、方法、成员内部类、代码块
不能修饰最外面的类,也不能修饰任何构造器
2,用它修饰后有什么不同
(1)修饰属性
a,是该类所有对象共享的
b,static修饰的静态变量的值存储在”方法区”,实例变量存储在“堆”,局部变量在“栈”中
c,static修饰的属性,初始化的时机不同,在类初始化时初始化的,比创建对象要早,并且只初始化一次
注:实例变量每个对象是独立的,各自存储了一份;类变量,静态变量是一个类存储了一份,所有对象共享的
d,static修饰的属性,它的get/set也是static的
注:static方法中不可用this(类名.静态变量=值)
(2)修饰方法
a,不用“对象.”就可调用,用“类名.”调用
b,static修饰的方法中,不能使用this.super关键字
c,static修饰的方法中,不能直接使用非静态的属性和方法
d,static修饰的方法,不能被重写,可以继承,静态方法,在编译时就确定
类的第四个成员:代码块
(1)作用:为属性初始化
非静态代码块:为非静态属性初始化,或者说辅助(对象)初始化
静态代码块:为静态属性初始化,或者说辅助类初始化
(2)语法格式:
【修饰符】class 类名{
{
//非静态代码块
}
static{
//静态代码块
}
}
(3)什么时候执行代码块
a,静态代码块:在类初始化时执行,只执行一次
b,非静态代码块:在实例初始化时执行,创建一个对象执行一次
c,子类初始化时父类没初始化,会先初始化父类
d,子类的实例初始化会导致父类的实例初始化,先执行父类的<linit>,后执行子类的<linit>
类初始化:
每一个类,编译器会自动生成一个<clinit>()称类初始化方法,这个方法的方法体由两部分组成
(1)静态变量的显式赋值语句
(2)静态代码块的语句(这两个部分,谁在上面谁先执行)
实例初始化:
每一个构造器编译器会自动生成一个对应的·<linit>()称实例初始化方法,这个方法的方法体由三部分组成
(1)非静态变量的显式赋值语句
(2)非静态代码块的语句
(3)对应的构造器语句((1)和(2)谁在前谁先执行,构造器永远最后执行)
执行顺序:
(1)先加载并初始化父类<clinit>()
(2)加载并初始化子类<clinit>()
(3)创建子类对象
a,导致父类的<linit>实例初始化方法执行
b,子类的<linit>实例初始化方法执行
关键字:final
1,final可以修饰什么
类、变量、方法
类:包括外部类和内部类
变量:局部变量、实例变量、类变量
方法:静态方法、非静态变量
2,它修饰后有什么不同
(1)修饰类:即class前面出现了final,表示这个类是最终类,即这个类不能被继承了,没有子类
(2)修饰方法:返回值前出现了final,表示这个方法是最终实现版本,即这个方法不能被重写
(3)修饰变量:即在变量数据类型前出现了final,表示了这个变量的值不能被修改,它是常量,一般要求常量名大写,每个单词之间使用—。常量必须赋值
抽象类
当某个父类需要体现它们的子类们的共同特性,例如:共同的方法,但这个方法在父类中无法给出合理的实现,具体的实现由子类完成。那么,这样的方法我们可以设计为抽象方法
一,抽象方法
【修饰符】abstract 返回值类型 方法名([形参列表]);
二,抽象类
【权限修饰符】abstract class 类名{
}
抽象类特点:
(1)抽象类不能实例化,即抽象类不可直接创建对象
(2)抽象类就是被用来继承的,子类继承抽象类时,必须重写抽象方法,否则子类也得是抽象类
(3)包含抽象方法的类必须是抽象类,反过来,抽象类可以没有抽象方法,目的是为了 不让你创建它的对象,让你创建它的子类的对象