8.12 static 详讲
- static 修饰的变量(静态变量)
- static 修饰的方法(静态方法)
- static 的存在 涉及到 后期学习的 多线程。
所以 static 它原来 叫做 "静态修饰符"啊。那么静态修饰符的作用到底是什么呢?
static 静态修饰符,无论是在 C/C++ 中,还是 Java 中,它的作用基本是一致的。static 静态 一词 就代表着 生命周期会很长,就像静止了一般。被static修饰的 变量或方法,一旦存在或被创建,将会一直保留 到 程序终止结束! 具有这种特性的它,在 “类里面”,就会发生特殊的特性,因为 类是一个抽象化模板,在程序执行开始的时候,就已经被创建和存在了,而被static 修饰的方法和变量 也会随着 类的存在和创建,而被 存在和创建。也就是说 类一旦出现,它就出现了。那么什么时候 会消失呢?答:程序结束后。
由于 static 修饰的东西,在程序结束后才能消失,而类一旦存在,它就已经存在了。并且 我们的对象 在被销毁后,对象相关的 变量和方法 是会被销毁的!所以 static 为了保持自己的特性!它是 不可能 所属于 “对象” 的。那么就只能 所属于 “类”!(但 更加 NB 的是,每个对象 还都可以 有 调用它的能力。)
- 类变量
因为 被 static 的变量,所属于 “类”,所以我们也可以管它叫做 “类变量” !
调用格式: 类名.变量名 / 变量名(在类里的话)
我们 非常建议 大家用 “类名.变量名 / 类名.方法名” 来调用。
- 类方法(静态方法)
package static详讲;
public class Student {
private static int age;//静态的变量
private double score;//非静态变量
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.score);
System.out.println(age);
System.out.println(Student.age);
}
//静态方法
public static void go()
{
age = 100;
System.out.println("静态 go");
}
//非静态方法
public void run()
{
score = 200;
System.out.println("非静态 run");
}
}
非静态 方法 无法直接 调用,只属于 对象。
静态方法 无法 使用 非静态 变量 也 无法调用 非静态方法。
为什么 静态方法 无法使用 非静态的变量和方法呢?答:这个其实与 类的加载顺序有关。在后期笔记章节里会讲到!
现在这需要理解,因为它们不是 静态的,所以 静态的方法 用不了 就完事了。
8.12.1 代码块和静态代码块
代码块 是 从 C/C++ 那里 保留下来的 一个 特性传统,只 由 {} 包含,没有其它格式。
注意:
- 代码块的作用域 仅仅 就是 {} 这一块!
- 代码块 属于 一个整体,是为了 提示我们 程序员 这一部分是一个 整体。
8.12.1.1 代码快的作用域
- 非静态代码块 (可以用来 给对象赋初始值)
package static详讲;
public class Person {
{
int age = 100;
//代码块(匿名)
}
int age;
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.age);
}
}
你会发现 你这样子写,并不会 报错,也就是说 并不冲突!这是因为 代码块 自成一派,是一个整体,作用域也仅是那一小块儿!然后 这段代码最后输出的 是 0 。
8.12.1.2 静态代码块(用来做程序初始化的操作)
静态代码块 比 代码块 执行的早!而代码块 是 执行在 构造器 前面的!也就是说,静态代码块往往是项目启动的时候,你需要自动执行什么代码和功能。就要去用静态代码块!不信的话,可以测试以下。
package static详讲;
public class Person {
{
int age = 100;
System.out.println("代码块");
//代码块(匿名)
}
static {
System.out.println("静态代码块");
//静态代码块 总是用来放一些 初始化数据
}
Person()
{
System.out.println("无参构造");
}
int age;
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.age);
}
}
所以,构造器 并不是 类 最早执行的 东西!代码块比它执行的早,静态代码块 比他俩 执行的都早!
因为 static 代码块,执行完一次后,就一直存在了。所以 当第二次 创建 对象的时候,不会再次 执行!而代码块 是 伴随着 每个 对象而诞生的。每创建一个对象,都需要执行一次!
8.12.2 静态导入包(新奇玩法)
格式:import static 包.方法;
package static详讲;
import static java.lang.Math.random;//静态导入包,可以直接 导入 方法
import static java.lang.Math.PI;
public class Main {
public static void main(String[] args) {
System.out.println(random());//导入完方法后
System.out.println(PI);
}
}
有点儿 像 C/C++ 中 namespace 的声明。
8.12.3 final 断子绝孙
凡是被 final 修饰过的 类,就是 最终状态类,不允许对它做之后的操作。也就是说 这个类 无法 被其它类 继承!
package static详讲;
public final class A { // 常 类 (最终形态类)
}
package static详讲;
public class B extends A {//无法 继承 最终形态的类
}