一、知識基礎
java加載類進內存均是通過jvm的類加載器完成。java類在內存的唯一標誌,其實是通過類加載器+類全名(包名+類名)。不同的類加載器加載同一個類是不會出現衝突的。
java的反射機制,是jdk提供的一套api,通過使用類加載器將指定的類動態加載進內存的方法。
二、目標
使用java反射機制創建一個實例對象,該類的構造方法的參數列表是可變長度的。
三、代碼示例
try {
AInterface ai = Class.forName("com.sun.test.myapp.AClass", true,
Thread.currentThread().getContextClassLoader())
.asSubclass(AInterface.class)
.getDeclaredConstructor(String[].class).newInstance(new Object[] {
new String[] {"b", "c"}
});
System.out.println(ai.getClass().getSimpleName() + "::" + ai.getS0());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
上面代碼中AClass的如下
public class AClass implements AInterface {
private String s0;
public AClass() {
s0 = "a";
}
public AClass(String... args) {
this.s0 = "::";
if(args.length >= 1) {
for(String s : args) {
this.s0 += s;
}
}
}
public AClass(String s0) {
this.s0 = s0;
}
public AClass(String s0, boolean f) {
if(f) {
this.s0 = s0;
}
}
public String getS0() {
return this.s0;
}
}
我們在getDeclaredConstructor中定義構造方法的參數類型使用的是數組類型,在newInstance進行實例創建時傳遞給構造方法的參數列表是一個數組,但該數組需要被Object數據包裹,直接傳會報錯。
四、結語
因爲,在使用java反射時,創建可變長參數列表的構造方法的實例對象時,遇到一些問題,經過幾番嘗試才成功,故記錄下來。