1. 在進行單例反射操作的時候報錯:newInstance wrong number of arguments
public class Lazy {
private static boolean initialized = false;
private Lazy() {
synchronized (Lazy.class){
System.out.println("lazy : " + initialized);
if (!initialized){
initialized = true;
}else {
throw new RuntimeException("單例被反射");
}
}
}
public static final Lazy getInstance(){
return LazyHolder.instance;
}
private static class LazyHolder{
private static final Lazy instance = new Lazy();
}
}
Class<?> clazz = Lazy.class;
Constructor < ? > [] constructors = clazz.getDeclaredConstructors();
System.out.println("constructors size: " + constructors.length);
for (Constructor c:
constructors) {
c.setAccessible(true);
Object o = c.newInstance(new Object[] {null});
}
最開始的時候,Object o = c.newInstance()這樣使用直接報錯,構造方法都不能進去需要添加參數才能進去.
但是構造體能進去了,仍然報wrong number of arguments
參考:https://stackoverflow.com/questions/14491699/java-reflections-error-wrong-number-of-arguments
**補充: getDeclaredConstructors()與getConstructors()差別是,前者public/private都get,後者隻拿public
2. 那問題來了,為什麼我Lazy類裡面隻有一個constructor,但是constructors傳回的長度是2呢
那我debug一下:

發現竟然是這樣的:constructor[1]裡面的才是我想要的private的constructor,是以直接newInstance()不帶參是不報錯的
那$1是什麼?
原來Java中類後面$1表示類中存在内部類,普通内部類編譯出class為内部類類名$1,匿名内部類編譯成class為類$1
也就是說constructor[0]是内部類的constructor,再看debug
我們看到c1的constructor是有參數要求的
對比c2,可以看c2是沒有的:
3.那麼匿名内部類的constructor究竟是什麼樣子的呢?
簡要一說,匿名内部類繼承自父類
class testtest.InnerTest$1 extends testtest.Test
這個類有構造方法:
testtest.InnerTest$1(testtest.InnerTest, int);
這裡也很容易了解,兩個參數,一個是匿名内部類的外部類引用直接傳了進來,這也是我們能在内部類中直接通路外部類成員的實作原理。另外一個就是int類型的參數了。也就是說其實編譯器自動的給我們添加了帶參數的構造方法。
是以核心就在這裡,多了一個int的參數了
for (Constructor c:
constructors) {
System.out.println(c.getClass());
c.setAccessible(true);
if (c.getParameterTypes().length == 1){
Object o = c.newInstance(new Object[] {null});
}else{
Object o = c.newInstance();
}
}