本篇文章將分為兩部分:
1、通過反射獲取類的構造方法
獲取某一個類中的所有的構造器,通常分為兩個步驟:
①明確操作的是哪一份字節(jié)碼對象
②獲取構造器
Class類獲取構造器方法:
Constructor類:表示類中構造器的類型,Constructor的實例就是某一個類中的某一個構造器
public Constructor<?>[] getConstructors():
該方法只能獲取當前Class所表示類的public修飾的構造器
public Constructor<?>[] getDeclaredConstructors():
獲取當前Class所表示類的所有的構造器,和訪問權限無關
public Constructor<T> getConstructor(Class<?>... parameterTypes)
:獲取當前Class所表示類中指定的一個public的構造器
參數:parameterTypes表示:構造器參數的Class類型
如:
public User(String name) Constructor c = clz.getCOnstructor(String.class);
public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes)
:獲取當前Class所表示類中指定的一個的構造器,和訪問權限無關
<pre><code>
class User {
public User() {}
public User(String name) {}
private User(String name, int age) {}
}
public class ConstructorDemo {
public static void main(String[] args) throws Exception {
//1、先找到被調用構造器所在類的字節(jié)碼
Class<User> clz = User.class;
//2、獲取所有構造器
Constructor<?>[] cs = clz.getConstructors();
for (Constructor<?> constructor : cs) {
System.out.println(constructor);
}
System.out.println("---------------------------");
//2、獲取指定公有帶參數構造器(獲取指定公有構造器)
Constructor<?> c = clz.getConstructor(String.class);
System.out.println(c);
System.out.println("---------------------------");
//獲取指定公有無參數構造器(獲取指定公有構造器)
c = clz.getConstructor();
System.out.println(c);
System.out.println("---------------------------");
//2、獲取指定私有構造器
c = clz.getDeclaredConstructor(String.class,int.class);
System.out.println(c);
}
}
</pre></code>當我們在代碼中添加如下代碼:
<pre><code>
c = clz.getDeclaredConstructor(int.class);
System.out.println(c);
2、創(chuàng)建對象
調用構造器,創(chuàng)建對象:
Constructor<T>
類:表示類中構造器的類型,Constructor
的實例就是某一個類中的某一個構造器
常用方法:
public T newInstance(Object...initargs)
:如調用帶參數的構造器,只能使用該方式.
參數:initargs
:表示調用構造器的可變實際參數
返回:返回創(chuàng)建的實例,T
表示Class
所表示類的類型
如果:一個類中的構造器可以直接訪問,同時沒有參數.,那么可以直接使用Class類中的newInstance
方法創(chuàng)建對象.
public Object newInstance()
:相當于new 類名();<pre><code>
class User {
public User() {
System.out.println("User()");
}
public User(String name) {
System.out.println("User(String name) " + "name = "+name);
}
private User(String name, int age) {
System.out.println("User(String name, int age) " + "name = "+name+" age = "+age);
}
}
public class ConstructorDemo {
public static void main(String[] args) throws Exception {
//1、先找到被調用構造器所在類的字節(jié)碼
Class<User> clz = User.class;
//2、獲取指定公有帶參數構造器(獲取指定公有構造器)
Constructor<?> c = clz.getConstructor(String.class); //
//3、實例化對象
c.newInstance("huangweiyong");
System.out.println("---------------------------");
//獲取指定公有無參數構造器(獲取指定公有構造器)
c = clz.getConstructor();
//3、實例化對象
c.newInstance();
System.out.println("---------------------------");
//直接調用Class類的newInstance方法構造對象
//3、實例化對象
clz.newInstance();
System.out.println("---------------------------");
//、獲取指定私有構造器
c = clz.getDeclaredConstructor(String.class,int.class);
//設置私用方法的可訪問(切記,這里必須設置,否則會拋出下圖的異常)
c.setAccessible(true);
//3、實例化對象
c.newInstance("huangweiyong",18);
}
}</pre></code>c.setAccessible(true);
如果上述代碼在調用私有構造函數時沒有設置成true
或者不寫,會拋出下圖異常:
為了安全性考慮,private成員外界不準訪問.
但是問題是,我偏要訪問:此時就要告訴成員在運行期間忽略掉該安全檢查.
解決方案:調用
AccessibleObject
類中的publicvoid setAccessible(boolean flag)
方法:設置是否可訪問setAccessible(true)
:可訪問的又因為
Constructor
是AccessibleObject
子類,所以Constructor
中具有該方法.(這一點千萬不要忘記,切記切記!!!!!!)