Static 与 Final 详解

一、 Static详解

Static 关键字可修饰:
  • 成员变量: Static修饰成员变量时,作为全局变量

    • 静态变量不再绑定类的实例,只与类的加载有关
    • 类的所有实例共享同一个静态变量实例
  • 方法: Static修饰方法时,为静态方法

    • 调用方式: 1. 类名.method(); 2. 对象.method();
    • 非静态方法能调用静态方法,但静态方法中不能调用非静态方法,这涉及类加载的先后顺序问题

1. 调用static修饰的变量:

package com.zctou.oop.demo09;

public class Student {
    //Static与Final 演示
    private static int age; //静态变量
    private double score; //非静态变量

    public static void main(String[] args) {
        //调用static修饰的成员变量
        //1.类名.属性
        System.out.println(Student.age);
        //Student.score; //不能直接调用非静态属性
        //2. new 对象.属性
        System.out.println(new Student().score);
        System.out.println(new Student().age);
    }
}
//输出:
0
0.0
0
2种调用static方法前面都已经详细分析过,静态属性的调用也是一样的,这里要注意的是类名.属性不能调用非静态属性。

2. 调用Static方法:

package com.zctou.oop.demo09;

public class Teacher {
    private static void eat() {
        System.out.println("饱吃一顿");
        //shout(); //报错,静态方法不能调用非静态方法
    }

    public void shout() {
        System.out.println("叫了一哈");
        //eat(); 非静态方法可以调用静态方法
    }

    public static void main(String[] args) {
        Teacher.eat();
        //eat(); 同一类中,静态方法可以直接调用类中的其他静态方法
        //Teacher.shout(); //报错: 无法从静态上下文中引用非静态 方法 shout()
        Teacher t = new Teacher();
        t.shout();
        t.eat();

    }
}
  • 静态方法,非静态方法都可以调用静态方法。即带static的方法可以被随便调用。
  • 静态方法不能调用非静态方法。即带static的方法只能调用同样带static的方法。

3. 匿名代码块与静态代码块

  • 匿名代码块

    匿名代码块就是{}里的代码,常用于赋初始值,每次创建对象都会执行。

  • 静态代码块:

    静态代码块就是 static {}, 最最先执行的代码,只在类加载时执行一次,多次创建类不会重复执行。

package com.zctou.oop.demo09;

public class Person {
    //匿名代码块和静态代码块演示

    public Person() {
        System.out.println("无参构造被执行了");
    }

    static {
        System.out.println("静态代码块执行了");
    }
    {
        System.out.println("匿名代码块执行了");
    }
    public static void main(String[] args) {
        Person p = new Person();
        System.out.println("================");
        Person p2 = new Person();
        System.out.println("================");
        Person p3 = new Person();
    }

}

输出:
静态代码块执行了
匿名代码块执行了
无参构造被执行了
================
匿名代码块执行了
无参构造被执行了
================
匿名代码块执行了
无参构造被执行了

可以看到,与代码的顺序无关,

  1. 程序先执行的是静态代码块,且只执行一次。
  2. 再来是执行匿名代码块,每创建一个对象执行一次。
  3. 最后是执行构造器的代码,也是每创建一个对象执行一次。

4. 静态导入包

静态导入包语法格式:(用处不大)

import static 包路径

如:

package com.zctou.oop;
import static java.lang.Math.PI; //静态导入包
import static java.lang.Math.random;
public class Application {
    public static void main(String[] args) {
        System.out.println(Math.random());
        System.out.println(random());
        System.out.println(PI);
    }

}

二、 Final关键字

Final表示最终,也就是不可更改,存储在常量池里。如果一个类带上final关键字修饰符,那么这个类就不能被继承,也就是这个类不可能有子类(断子绝孙)。

Final 可以修饰

  • 类 :

    final修饰类时,这个类不能被继承,不能有子类

  • 方法

    final修饰的方法,不可被子类重写。

  • 变量

    final修饰变量时,这个类就变了“常量”,从第一次被赋值后就不可被更改。

文章目录