天天看點

執行個體化隻包含私有帶參構造函數對象

有如下類定義,請不用關注類的實際意義:

public class Person {
    static final int DEFAULT_SEX = ;
    public static int sex = DEFAULT_SEX;
    public String name = "default";

    static {
        System.out.println("------person initialed------");
    }

    private Person(String name) {
        super();
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ",sex=" + sex + "]";
    }
}
           

從反射角度,最初我們會寫這樣的代碼:

public static void main(String[] args) throws Exception {
    Constructor<Person> constructor = Person.class.getDeclaredConstructor(String.class);
    constructor.setAccessible(true);
    Person p = constructor.newInstance("guor");
    System.out.println(p);
}
           

輸出:

------person initialed------
Person [name=guor,sex=1]
           

使用反射機制的情況,基本上對類定義比較敏感,一旦類構造函數發生改變,上面的代碼很有可能發生運作時錯誤。

今天了解sun.misc.Unsafe的時候,發現如下另外一種寫法,可謂是萬能的初始化:

@SuppressWarnings("restriction")
public static sun.misc.Unsafe getUnsafe() throws Exception {
    Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
    f.setAccessible(true);
    return (sun.misc.Unsafe) f.get(null);
}

@SuppressWarnings({ "restriction" })
public static void main(String[] args) throws Exception {
    sun.misc.Unsafe unsafe = getUnsafe();
    Person p = (Person) unsafe.allocateInstance(Person.class);
    System.out.println(p);
}
           

輸出:

------person initialed------
Person [name=null,sex=1]
           

需要注意的是,第二種初始化的方式,對象的成員變量并不會被初始化

繼續閱讀