static
static修飾的變量和方法統(tǒng)一屬于類的靜態(tài)資源,是類實例之間共享的
JDK將不同的靜態(tài)資源放在不同的類中,而不是把所有靜態(tài)資源放在一個類中,可以實現靜態(tài)分類(不同類有自己的靜態(tài)資源),避免重名和靜態(tài)資源無限膨脹.
靜態(tài)變量和靜態(tài)方法
- 被static修飾的變量屬于類變量,可以通過
類名.變量名直接引用,不需要new - 被static修飾的方法屬于類方法,可以通過
類名.方法名直接引用,不需要new
靜態(tài)資源屬于類,但是獨立于類存在,靜態(tài)資源是類初始化的時候加載的,而非靜態(tài)資源那是類new的時候加載的。
類的初始化早于類的new,比如Class.forName("xxx")方法,就是初始化一個類,但是并沒有new,只是加載這個類的靜態(tài)資源,所以:
- 靜態(tài)方法不能引用非靜態(tài)資源
- 靜態(tài)方法可以引用靜態(tài)資源
- 非靜態(tài)方法可以引用靜態(tài)資源
錯誤示例
public class A
{
private int i = 1;
public static void main(String[] args)
{
// 錯誤代碼,靜態(tài)方法不能有引用非靜態(tài)資源
i = 1;
}
}
靜態(tài)塊
靜態(tài)塊用于初始化一個類的時候操作用的,和靜態(tài)變量、靜態(tài)方法一樣,靜態(tài)塊里面的代碼只執(zhí)行一次,且只在初始化類的時候執(zhí)行。
- 靜態(tài)資源的加載順序是嚴格按照靜態(tài)資源的定義順序來加載的
public class A {
private static int a = B();
static {
System.out.println("A.static block");
}
public static void main(String[] args) {
System.out.println("a = " + a);
}
public static int B() {
System.out.println("A.B()");
return 1;
}
}
打印結果:
A.B()
A.static block
a = 1
- 靜態(tài)代碼塊對于定義在它之后的靜態(tài)變量可以賦值,不可以訪問
public class A {
static {
c = 3;
System.out.println(c); // Cannot reference a field before it is defined 無法在定義字段之前引用該字段
}
private static int c;
}
- 靜態(tài)代碼塊是嚴格按照 父類靜態(tài)代碼塊>>子類靜態(tài)代碼塊 的順序加載的,且只加載一次
public class A {
static {
System.out.println("A.static block");
}
public A() {
System.out.println("A.constructor()");
}
}
class B extends A {
static {
System.out.println("B.static block");
}
public B() {
System.out.println("B.constructor()");
}
public static void main(String[] args) {
new B();
new B();
}
}
打印結果:
A.static block
B.static block
A.constructor()
B.constructor()
A.constructor()
B.constructor()
兩個具有繼承關系類的初始化順序
父類的(靜態(tài)變量、靜態(tài)代碼塊)>> 子類的(靜態(tài)變量、靜態(tài)代碼塊)>> 父類的(變量、初始化塊、構造器)>> 子類的(變量、初始化塊、構造器)
static修飾類
使用static修飾類時,說明這個類時靜態(tài)內部類,也就是匿名內部類。
public class A {
static class C {
static {
System.out.println("C.static block");
}
public C() {
System.out.println("C.constructor()");
}
}
static {
System.out.println("A.static block");
}
public A() {
System.out.println("A.constructor()");
}
public static void main(String[] args) {
new A();
new C();
}
}
打印結果 :
A.static block
A.constructor()
C.static block
C.constructor()
import static
指定導入某個類中的指定靜態(tài)資源,不需要類名.資源名,可以直接使用資源名。
注意一下,import static必須這么寫,而不能寫成static import。
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;
//import static java.lang.Math.*; 導入Math中所有靜態(tài)資源
public class AA {
public static void main(String[] args) {
System.out.println(Math.abs(-2.6));
// 輸出 : 2.6
System.out.println(sin(2));
// 輸出 : 0.9092974268256817
System.out.println(sqrt(4));
// 輸出 : 2.0
}
}