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();
}
}
输出:
静态代码块执行了
匿名代码块执行了
无参构造被执行了
================
匿名代码块执行了
无参构造被执行了
================
匿名代码块执行了
无参构造被执行了
可以看到,与代码的顺序无关,
- 程序先执行的是静态代码块,且只执行一次。
- 再来是执行匿名代码块,每创建一个对象执行一次。
- 最后是执行构造器的代码,也是每创建一个对象执行一次。
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修饰变量时,这个类就变了“常量”,从第一次被赋值后就不可被更改。