Java基础(五)--静态变量和方法

静态变量

  • 会被所有的实例化出来的对象共享该类的static变量
  • 可以通过类名直接访问
  • 静态变量 jdk8 以前是分配在静态域里面,之后是分配到堆里面
  • static 变量实在类加载的时候生成的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class ChildGame{

public static void main(String[] args) {
Child child1 = new Child("小孩1");
child1.join();

Child child2 = new Child("小孩2");
child2.join();

System.out.println("加入游玩的人数"+child1.getCount());
}

}

class Child {
private static int count;
private String name;

public Child(String name) {
this.name = name;
}

public int join(){
Child.count ++;
return Child.count;
}

public int getCount(){
return Child.count;
}
}

静态方法

  • 静态方法可以通过类名调用,也可以通过对象调用,但是静态方法中不能使用this
  • 只能访问静态成员或者方法
  • 普通成员方法既可以访问静态的也可以访问非静态的

代码块

  • 加载类时执行

  • 注意事项

    • static 代码块只在类加载时执行一次,非static代码块在每次创建对象时都会执行
    • 类被加载的三种情况
      1. 创建对象实例时(new)
      2. 创建子类对象实例,父类也会被加载
      3. 使用类的静态成员时(静态属性,静态方法)
    • 创建一个对象时,在一个类中的调用顺序
      1. 调用静态代码块和静态属性初始化(当有多个时按照它们的定义顺序调用)
      2. 调用普通代码块和普通属性的初始化(当有多个时按照它们的定义顺序调用)
      3. 调用构造方法
    • 创建一个子类对象时(有继承关系的子类),它们的静态代码块、静态属性初始化、普通代码块、普通属性初始化、构造方法的调用顺序
      1. 父类的静态代码块和静态属性初始化[优先级一致按照定义顺顺序执行]
      2. 子类的静态代码块和静态属性初始化[优先级一致按照定义顺顺序执行]
      3. 父类的普通代码块和普通属性初始化[优先级一致按照定义顺顺序执行]
      4. 父类的构造方法
      5. 子类的普通代码块和普通属性初始化[优先级一致按照定义顺顺序执行]
      6. 子类的构造方法
    • 静态代码块只能调用静态成员和静态方法,普通代码块可以调用任意成员
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    public class CodeBlock {
    public static void main(String[] args) {
    new B();
    }
    }

    class A {

    public static int a = getA();
    static {
    System.out.println("A 静态代码块被调用..");
    }

    public int aa = getAA();
    {
    System.out.println("A 普通代码块被调用..");
    }

    public A() {
    System.out.println("A 构造方法被调用..");
    }
    public static int getA(){
    System.out.println("A getA被调用..");
    return 100;
    }

    public static int getAA(){
    System.out.println("A getAA被调用..");
    return 100;
    }
    }

    class B extends A{
    public static int b = getB();
    static {
    System.out.println("B 静态代码块被调用..");
    }

    public int bb = getBB();
    {
    System.out.println("B 普通代码块被调用..");
    }

    public B() {
    System.out.println("B 构造方法被调用..");
    }
    public static int getB(){
    System.out.println("B getB被调用..");
    return 100;
    }

    public static int getBB(){
    System.out.println("B getBB被调用..");
    return 100;
    }
    }

    静态方法和属性的应用–单例设计