0x00 从一个有意思的问题开始
public static void main(String[] args) {
// doSomeThing;
}
这是 Java 代码中的入口函数,应该是用的最多的代码了,但不知道你想过没有,为什么一定要用 static 关键字修饰 main 方法?下面我们一起来分析。
0x01 static 关键字有什么用
首先我们要明白 static 能用来修饰什么东西?
简单来说,主要是下面三种:
-
修饰成员变量
-
修饰成员方法
-
修饰代码块
那么,用不用 static 修饰有什么区别呢?
-
对于成员变量而言
static 修饰的静态成员变量在类加载时初始化,存放在数据段中,有且仅有一份,所有类的实例共享同一个静态变量,可以通过类名调用,也可以通过对象实例调用。
-
对于成员方法而言
其实最重要的就是一条:可以通过类名直接访问,不依赖于任何对象!也就是说静态方法的执行可能先于任何对象的创建,因此与对象相关的变量、方法都不允许在静态方法中使用,比如:
-
静态方法中不允许使用 this 、super指针
-
静态方法中不允许使用非静态的方法或变量
-
静态方法不允许使用 abstract 进行修饰
静态方法的这个特点也就回答了开始提出的问题,因为 main 方法在执行时,没有任何一个对象被创建,所以,main 必须是静态方法。
但同时,需要注意的是,静态方法与静态变量一样,都允许通过对象实例调用!
-
-
对于代码块而言
static 修饰的代码块通常用于初始化静态数据成员,对于一些不需要在每个对象中进行初始化的变量,通常放在 static 代码块中,仅在类加载时初始化一次。
0x02 应用场景
静态方法的应用场景挺多了,在 Java 中大量存在,如 Math 类的各种方法等等,静态变量常用的是实现类的实例间的数据共享,举个栗子:
package com.zeamonk;
public class StaticTest {
public static void main(String[] args) {
// 创建三个对象,由于共享了 sid,实现了 book id属性的自增
Book book1 = new Book("大秦帝国");
Book book2 = new Book("乌合之众");
Book book3 = new Book("原则");
}
}
class Book {
static int sid = 0; // 静态成员变量,对所有类的实例共享
int id;
String name;
Book(String _name) {
id = sid++;
name = _name;
System.out.println(name + " id = " + id);
}
}
代码很简单,由于 sid 是保存在数据段中的,有且仅有一份,所以 Book 对象的每一个实例在创建时都会调用 sid复制给自身的 id,同时将 sid 自增。
0x03 需要注意的问题
-
static 修饰的变量、方法或代码块在类加载时指执行,且仅执行一次。
-
多个 static 代码块在执行时按定义顺序执行
-
静态变量被修改后无法恢复,类似于 C/C++ 中的全局变量
欢迎关注公众号-
网友评论