java基础复习 - 7 - static、代码块、final

类变量和类方法

静态变量放在class类实例的尾部,class对象确实在堆中
无论在哪里共识:

  1. static变量是同一个类所有对象共享
  2. static类变量,在类加载的时候就生成了

定义语法

  1. 访问修饰符 static 数据类型 变量名
  2. static 访问修饰符 数据类型 变量名
  3. 对象名. 和类.都可以访问

类方法

  1. 形式也是两种static可以放在访问修饰符后面或者前面
  2. 访问方式也是对象.或者类.
  3. 类方法和普通方法都是随着类的加载而夹杂,将结构信息存储在方法区:类方法中无this的参数,普通方法中隐含着this的参数
  4. 类方法中不允许使用和对象有关的关键字,比如this和super。
  5. 类方法中只能访问静态变量或静态方法

代码块

代码块又称为初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不能通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。

[修饰符]{
    代码
}
  1. 修饰符可选,只能写static
  2. 代码块氛围两类使用static修饰的叫静态代码块
  3. ;可以协商也可以省略
  4. 相当于另外一种形式的构造器,可以做初始化的操作
  5. 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性
    注意事项
  6. static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次(类只会加载一次)。如果是普通代码块,每创建一个对象,就执行。
  7. 类什么时候被加载
    1. 创建对象实例(new)
    2. 创建子类对象实例,父类也会被加载
    3. 使用类的静态成员时(静态属性、静态方法)
  8. 普通的代码块,在创建对象实例时,会被隐式的调用,被创建一次就会调用一次。如果只是使用类的静态成员时,普通代码块并不会被执行(只是调用静态属性、方法并不会创建对象)
     /*
         当存在继承关系时,类的信息加载会从父类开始加载
         常见对象也会先开会父类的空间
         所以Student.name 此时会执行Student的静态代码块(加载类信息但不会创建对象),  Student的普通代码块和构造器不会调用
         此时会先输出父类静态代码块的信息再输出子类静态代码块的信息  结束
         当创建子类对象时 new
         会先加载父类的信息(静态代码块执行)再加在子类的信息(静态代码块执行)
         在创建对象开辟父类空间(父类的代码块-父类的构造器)
         再开辟子类的空间(子类代码块-子类构造器)
         重点:代码块的顺序执行
     */
    
  9. 创建一个对象时,在一个类调用顺序是:(重点)
    1. 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果多个静态代码块和多个静态变量初始化,按照他们定义的顺序调用)
      private static int n1 = getN1();
      
      static {
          System.out.println("A 静态代码块01");
      }
      
      public static int getN1() {
          System.out.println("getN1被调用");
          return 100;
      }
      // 打印顺序 getN1被调用  A 静态代码块01
      
    2. 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块个多个普通属性初始化,按照定义顺序调用)
    3. 调用构造方法
  10. 构造方法(构造器)的最前面其实隐含了super()和调用普通代码块
  11. 创建一个子类时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:
    1. 父类的静态代码块和静态属性(优先级一样,按照定义顺序执行)
    2. 子类的静态代码块和静态属性(优先级一样,按照定义顺序执行)
    3. 父类的普通代码块和普通属性初始化(优先级一样,按照定义顺序执行)
    4. 父类的构造方法
    5. 父类的普通代码块和普通属性初始化(优先级一样,按照定义顺序执行)
    6. 子类的构造方法
  12. 静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员
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 可以修饰类、属性、方法和局部变量

  1. 当不希望类被继承时,可以用final修饰
  2. 当不希望父类的某个方法被子类覆写时,可以用final关键字
  3. 当不希望类的某个属性的值被修改,可以用final
  4. 当不希望某个局部变量被修改,可以使用final修饰
    细节
  5. 初始化的方式
    1. 定义时
    2. 构造器中
    3. 代码块中
  6. 如果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 = ""; 错误的
    }
}
  1. final类不能继承,但是可以实例化对象
  2. 如果类不是final类,但含有final方法,则改方法虽然不能重写,但是可以被继承
  3. 一般来说,如果一个类已经是final类了,就没有必要再将方法秀事成final方法
  4. final不能修饰构造方法
  5. 包装类和String都是final类
posted @ 2022-03-27 22:00  杨大德  阅读(83)  评论(0)    收藏  举报