類加載的統一的原則-----
變量定義的先后順序決定初始化順序,而在不同變量之間,又存在着某些規則(先靜態對象,再非靜態對象)
靜態代碼塊屬於類,且在類加載時只執行一次,即使后面有類加載的條件也不會再次執行;
類加載條件:
1 創建類的實例
2 訪問某個類或接口的靜態變量,或者對該靜態變量賦值
3 調用類的靜態方法
4 反射(如Class.forName(""))
5 初始化一個類的子類,它的父類也會被初始化
6 java虛擬機啟動時被表明為啟動類的類(java test)
7 jdk1.7開始提供的動態語言 支持 :
java.lang.invoke.MethodHandle實例的解析結果REF——getSatic, REF_putStatic,REF_invokeStatic 句柄對應的類沒有初始化,則初始化
內部類的加載:
內部類:內部類是延時加載的,也就是說只會在第一次使用時加載。不使用就不加載。
示例:
package demo;
import demo.Enclosingone;
import demo.Enclosingone.InsideOne;
import demo.Enclosingone.InsideOne2;
class Enclosingone
{
static final int a=100;
static {
System.out.println("Enclosingone.enclosing_method():父類靜態代碼塊");
}
public Enclosingone() {
{
System.out.println("Enclosingone.Enclosingone():父類構造函數");
}
}
{
System.out.println("Enclosingone.enclosing_method():父類構造代碼塊");
}
public void name() {
{
System.out.println("Enclosingone.name():父類普通代碼塊");
}
}
public static class InsideOne {//靜態內部類
static{
System.out.println("Enclosingone.InsideOne.enclosing_method():靜態內部類");
}
}
public class InsideOne2{//內部類
//靜態內部類的加載不需要依附外部類,在使用時才加載。不過在加載靜態內部類的過程中也會加載外部類
//非靜態內部類不能使用靜態代碼塊(一般的非靜態類可以有靜態代碼塊)
//因為非靜態內部類相當於外部的非靜態成員變量,如果外部類要調用非靜態成員變量,則需要創建對象,
//進行調用;而非靜態內部類中有static代碼塊,那么在外部類加載的時候就會加載,不需要考慮外部狀態
//則與外部類的創建相駁論,所以靜態內部類不能創建靜態代碼塊
static final int a=200;//就近原則匹配a的值
//static final int a=6;
public InsideOne2() {
System.out.println(a);
}
}
@Override
protected void finalize() throws Throwable {
System.out.println("最后一次a:"+a);
}
}
class Enclosingonechild extends Enclosingone{
static {
System.out.println("Enclosingonechild.enclosing_method():子類靜態代碼塊");
}
public Enclosingonechild() {
{
System.out.println("Enclosingonechild.Enclosingonechild():子類構造函數");
}
}
{
System.out.println("Enclosingonechild.enclosing_method():子類構造代碼塊");
}
}
public class demo
{
public static void main(String[] args)
{
new InsideOne();//靜態內部類直接聲明使用//相當於外部類
System.out.println("-------------");
new Enclosingone().new InsideOne2();
System.out.println("--------------");
new Enclosingonechild().name();
System.out.println("--------------");
System.gc();//調用gc回收,觸發finalize方法;
}
}
輸出結果:
Enclosingone.InsideOne.enclosing_method():靜態內部類
-------------
Enclosingone.enclosing_method():父類靜態代碼塊
Enclosingone.enclosing_method():父類構造代碼塊
Enclosingone.Enclosingone():父類構造函數
200
--------------
Enclosingonechild.enclosing_method():子類靜態代碼塊
Enclosingone.enclosing_method():父類構造代碼塊
Enclosingone.Enclosingone():父類構造函數
Enclosingonechild.enclosing_method():子類構造代碼塊
Enclosingonechild.Enclosingonechild():子類構造函數
Enclosingone.name():父類普通代碼塊
--------------
最后一次a:100
最后一次a:100
