一、靜態內部類(靜態巢狀類)vs非靜態內部類(內部類)
靜態內部類
*靜態內部類只能訪問外部類的靜態方法和靜態屬性,如果是private也能訪問,其他則不能訪問,建立物件不依賴外部類
*靜態內部類可以定義靜態的屬性和方法
非靜態內部類
- 內部類可以訪問其所在類的屬性(包括所在類的私有屬性),內部類建立自身物件需要先建立其所在類的物件
- 可以定義內部介面,且可以定義另外一個內部類實現這個內部介面
- 內部類不能定義static元素
- 內部類可以多巢狀
總結
靜態內部類和外部類是相互獨立的,建立例項或者建立什麼型別的物件都不受限制
非靜態內部類是外部類的一部分,建立例項必須先建立外部類的例項,可以訪問外部類的所有屬性
二、類的初始化及物件建立
類的載入、連結、初始化
1.class檔案(二進位制)通過類的載入器(引導類載入器、自定義載入器)載入(雙親委派機制)到記憶體中,並建立java.lang.Class物件(類是一類事物的抽象,Class是類的抽象,抽象的抽象)
2.連結:
①驗證:驗證位元組碼檔案格式等是否正確
②準備:類的靜態變數分配記憶體,並設定預設值
③解析:符號引用轉換為直接引用
3.初始化
初始化階段是執行類構造器
類例項化的時機
1.使用new關鍵字建立物件
2.使用Class類的newInstance方法(反射機制)
3.使用Constructor類的newInstance方法(反射機制)
4.使用Clone方法建立物件
5.使用(反)序列化機制建立物件
類例項化的過程
static final 變數編譯階段分配記憶體空間並賦值→父類的類構造器
三、靜態內部類建立單例物件怎麼保證執行緒安全
package com.bo.singleton;
/*靜態內部類建立單例物件*/
public class StaticInnerTest {
public StaticInnerTest() {
System.out.println("靜態內部類無參建構函式");
}
public static StaticInnerTest getInstance() {
return Inner.sit;
}
//方法不需要設定同步
public static class Inner{
private static final StaticInnerTest sit = new StaticInnerTest();
}
public static void main(String[] args) {
StaticInnerTest s1 = StaticInnerTest.getInstance();
StaticInnerTest s2 = StaticInnerTest.getInstance();
System.out.println(s1==s2);
}
}
靜態內部類的特點:外部類載入時不需要載入靜態內部類,不被載入則不佔用記憶體,(延遲載入)當外部類呼叫getInstance方法時,才載入靜態內部類,靜態屬性保證了全域性唯一,靜態變數初始化保證了執行緒安全,所以這裡的方法沒有加synchronized關鍵字(JVM保證了一個類的 初始化在多執行緒下被同步加鎖)