一、static關鍵字的作用
1、可以用于修改類的成員變量、代碼塊和類
通過static可以将類的成員聲明為靜态成員,靜态的成員歸屬于整個類,而不是屬于某個對象。無論通過類還是對象通路靜态成員,操作的都是同一個靜态成員。
使用static修飾的代碼塊是靜态代碼塊,靜态代碼塊在類加載時執行。
靜态代碼塊和靜态方法不能通路非靜态屬性和方法。
靜态方法可以被繼承,但不能被覆寫(重寫);如果父類中定義的靜态方法在子類中被重新定義,那麼父類中定義的靜态方法将被隐藏。即:子類中如果有一個傳回類型,方法名和參數清單均與父類同名的靜态方法,那麼該子類實際上隻是将父類中該同名方法進行了隐藏,而非重寫。它們的行為也不具有多态性。
具體示例如下所示:
class Person {
private int age;
//2.使用static修飾的代碼塊是靜态代碼塊
static {
System.out.println("靜态代碼塊!");
}
//構造代碼塊
{
eat();
say();
age = 10;
}
//3. 靜态方法不能通路非靜态屬性和方法;因為其屬于對象,靜态方法執行時,
//對象還沒有建立
public static void say() {
//age = 12;
System.out.println("靜态方法說...");
}
public static void say(String str) {
//age = 12;
System.out.println("靜态方法說...");
}
//非靜态方法可以調用靜态方法和屬性
public void eat() {
say();
System.out.println("吃..." + name);
}
public static String name;
}
class Teacher extends Person {
//4.靜态方法不能被重寫,但是可以被繼承
//@Override
public static void say() {
System.out.println("子類靜态函數重寫");
}
}
public class Demo01 {
public static void main(String[] args) {
System.out.println(Person.name);
}
}
2.靜态的原理
使用static修改的成員屬性、成員方法和代碼塊在類加載時,被放到靜态區,并且隻加載一次;隻有當類被釋放時,靜态區所占的記憶體才會釋放。是以,使用不當會造成記憶體洩漏。其原理圖如下所示:
3.靜态和非靜态互訪
總結:靜态隻能通路靜态,普通可以通路所有(靜态、普通)
靜态屬性
靜态方法
普屬性
普通方法
靜态方法
可以
可以
不可以
不可以
靜态代碼塊
可以:前提是隻能通路到在靜态代碼塊之前聲明的靜态屬性,之後的不可以。
可以
不可以
不可以
普通方法
可以
可以
可以
可以
構造代碼塊
可以
可以
可以
可以
靜态方法可以重載嗎?
可以
靜态方法可以重寫嗎?
不可以
4.靜态的作用
JVM的入口方法main是靜态放方法
用作工具類:就是将一類常用功能提取成若幹方法寫入到一個類中,這些方法通常聲明為靜态方法友善使用。并且将該類的構造函數私有化,禁止建立對象,直接使用類名調用方法。比如常見的數學方法:Math.asin(double a)傳回一個值得正弦角度。
其他情況下使用靜态。
二、new關鍵字的作用
new關鍵字用于建立一個對象,在其建立對象的過程中大緻經曆了一下三個步驟;
1、将類加載到方法區
JVM首先會檢查這個new指令的參數能否在常量池中定位到一個類的符号引用;如果找不到就将該類加載到方法區并經過解析和初始化等步驟,計算執行個體化對象所需要的記憶體;為類的靜态變量賦予正确的初始值。
2、在堆中開辟一塊記憶體用于存儲新建立的對象
将類執行個體化出一個新的對象,根據類加載時計算所需的記憶體大小;在堆中開辟一塊記憶體,用于存儲新對象的成員屬性和方法區位址的引用。成員方法引用指向方法區中該對象對應的方法。
3、在棧中建立指向對象的引用
在棧中建立一個棧針,用于指向堆中建立的對象。