java基础复习 - 7 - static、代码块、final
类变量和类方法
静态变量放在class类实例的尾部,class对象确实在堆中
无论在哪里共识:
- static变量是同一个类所有对象共享
- static类变量,在类加载的时候就生成了
定义语法
- 访问修饰符 static 数据类型 变量名
- static 访问修饰符 数据类型 变量名
- 对象名. 和类.都可以访问
类方法
- 形式也是两种static可以放在访问修饰符后面或者前面
- 访问方式也是对象.或者类.
- 类方法和普通方法都是随着类的加载而夹杂,将结构信息存储在方法区:类方法中无this的参数,普通方法中隐含着this的参数
- 类方法中不允许使用和对象有关的关键字,比如this和super。
- 类方法中只能访问静态变量或静态方法
代码块
代码块又称为初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不能通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。
[修饰符]{
代码
}
- 修饰符可选,只能写static
- 代码块氛围两类使用static修饰的叫静态代码块
- ;可以协商也可以省略
- 相当于另外一种形式的构造器,可以做初始化的操作
- 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性
注意事项 - static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次(类只会加载一次)。如果是普通代码块,每创建一个对象,就执行。
- 类什么时候被加载
- 创建对象实例(new)
- 创建子类对象实例,父类也会被加载
- 使用类的静态成员时(静态属性、静态方法)
- 普通的代码块,在创建对象实例时,会被隐式的调用,被创建一次就会调用一次。如果只是使用类的静态成员时,普通代码块并不会被执行(只是调用静态属性、方法并不会创建对象)
/* 当存在继承关系时,类的信息加载会从父类开始加载 常见对象也会先开会父类的空间 所以Student.name 此时会执行Student的静态代码块(加载类信息但不会创建对象), Student的普通代码块和构造器不会调用 此时会先输出父类静态代码块的信息再输出子类静态代码块的信息 结束 当创建子类对象时 new 会先加载父类的信息(静态代码块执行)再加在子类的信息(静态代码块执行) 在创建对象开辟父类空间(父类的代码块-父类的构造器) 再开辟子类的空间(子类代码块-子类构造器) 重点:代码块的顺序执行 */ - 创建一个对象时,在一个类调用顺序是:(重点)
- 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果多个静态代码块和多个静态变量初始化,按照他们定义的顺序调用)
private static int n1 = getN1(); static { System.out.println("A 静态代码块01"); } public static int getN1() { System.out.println("getN1被调用"); return 100; } // 打印顺序 getN1被调用 A 静态代码块01 - 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块个多个普通属性初始化,按照定义顺序调用)
- 调用构造方法
- 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果多个静态代码块和多个静态变量初始化,按照他们定义的顺序调用)
- 构造方法(构造器)的最前面其实隐含了super()和调用普通代码块
- 创建一个子类时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:
- 父类的静态代码块和静态属性(优先级一样,按照定义顺序执行)
- 子类的静态代码块和静态属性(优先级一样,按照定义顺序执行)
- 父类的普通代码块和普通属性初始化(优先级一样,按照定义顺序执行)
- 父类的构造方法
- 父类的普通代码块和普通属性初始化(优先级一样,按照定义顺序执行)
- 子类的构造方法
- 静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员
class Person {
public static int total;
static {
total = 100;
System.out.println("in static block");
}
}
public class Test {
public static void main(String[] args) {
System.out.println("total=" + Preson.total);
System.out.println("total=" + Preson.total);
}
}
final
final 可以修饰类、属性、方法和局部变量
- 当不希望类被继承时,可以用final修饰
- 当不希望父类的某个方法被子类覆写时,可以用final关键字
- 当不希望类的某个属性的值被修改,可以用final
- 当不希望某个局部变量被修改,可以使用final修饰
细节 - 初始化的方式
- 定义时
- 构造器中
- 代码块中
- 如果final修饰的属性时静态的,则初始化的位置只能是 定义时或者静态代码块中都行,不能在构造器或者普通方法函数中赋值
class B extends A {// 对照静态方法中不能引用非静态的成员,普通方法都可以,这里普通方法不能对final修饰的静态成员初始化,需要在静态代码块或者定义时初始化
private static final String c;
static {
System.out.println("B 的 静态代码块");
c = "111";
}
public B() {
// c = "111"; 错误的
}
public void test1() {
// static final String a1 = ""; 错误的
}
}
- final类不能继承,但是可以实例化对象
- 如果类不是final类,但含有final方法,则改方法虽然不能重写,但是可以被继承
- 一般来说,如果一个类已经是final类了,就没有必要再将方法秀事成final方法
- final不能修饰构造方法
- 包装类和String都是final类

浙公网安备 33010602011771号