单例模式(Java内部类加载顺序)

你真的会写单例模式吗——Java实现
Android设计模式源码解析之单例模式
深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题
[转+注]单例模式的七种写法

其中提到静态内部类方法:
Java内部类详解
关于java内部类加载顺序的问题

顺序是:父类静态属性-》父类静态代码块-》子类静态变量-》子类静态代码块-》父类非静态变量-》父类非静态代码块-》父类构造函数-》子类非静态变量-》子类非静态代码块-》-》子类构造函数

这样的加载顺序不是绝对的 因为静态变量和静态代码块跟声明顺序有关。

对于如果静态代码块中调用静态变量,那么静态变量必须在静态代码块前面声明;如果静态代码块中没有调用静态变量,那么就跟顺序有关了,谁先声明谁先被加载。说白了还是顺序加载,之所以会出现“如果静态代码块中调用静态变量,那么静态变量必须在静态代码块前面声明”,是因为变量是声明,所以出现编译错误。

应用到内部类中 静态变量和静态代码块跟声明顺序有关。 这样就可以解释你的问题了。内部类也是类。

测试所用jdk版本1.8.0_20

类静态块-类静态属性这个跟顺序有关系 如果类静态属性在类静态代码块之前 那么类静态属性先初始化

package cn.canon.Single;
 
public class StaticInnerClassLoaderTime {
     
    public static class Inner {
        static {
            System.out.println("TestInner Static!");
        }
        public final static StaticInnerClassLoaderTime testInstance = 
                new StaticInnerClassLoaderTime(3);
    }
 
    public static StaticInnerClassLoaderTime getInstance() {
        return Inner.testInstance;
    }
 
    public StaticInnerClassLoaderTime(int i) {
        System.out.println("Test " + i + " Construct! ");
    }
     
    // 类静态属性
    public static StaticInnerClassLoaderTime testOut =
            new StaticInnerClassLoaderTime(1);
 
    public static int value = 3;
    // 类静态块
    static {
        System.out.println("Test Static" + value);
    }
 
    public static void main(String args[]) {
        StaticInnerClassLoaderTime t = new StaticInnerClassLoaderTime(2);
        StaticInnerClassLoaderTime.getInstance();
    }
}
Test 1 Construct! 
Test Static3
Test 2 Construct! 
TestInner Static!
Test 3 Construct!

你可能感兴趣的:(单例模式(Java内部类加载顺序))