建立對象:java
一、使用Class對象的newInstance()方法建立該Class對象的實例,此時該Class對象必需要有無參數的構造方法。安全
二、使用Class對象獲取指定的Constructor對象,再調用Constructor的newInstance()方法建立對象類的實例,此時能夠選擇使用某個構造方法。若是這個構造方法被私有化起來,那麼必須先申請訪問,將能夠訪問設置爲true;ide
Eg:對象
最簡單的:get
package junereflect624;it
class User{io
/*private User(){//將默認的構造方法私有化的話就不能夠再建立對象,兩種方法都是這樣編譯
}*/class
public String toString() {import
return "User對象建立成功!";
}
}
public class NewInstanceDemo6 {
public static void main(String[] args) throws Exception {
//傳統方式建立對象
System.out.println(new User());
//使用反射的方式
Class<User> c = User.class;
User u = c.newInstance();(直接newInstance的話必須保證默認的構造方法正常存在,也就是沒有被私有化!這是前提條件)
System.out.println(u);
}
}
複雜點的:更強大的第二種:
使用指定構造方法來建立對象:
獲取該類的Class對象。
利用Class對象的getConstructor()方法來獲取指定的構造方法。
調用Constructor的newInstance()方法建立對象。
AccessibleObject對象的setAccessible(boolean flag)方法,當flag爲true的時候,就會忽略訪問權限(可訪問私有的成員)。
其子類有Field, Method, Constructor;
若要訪問對象private的成員?
在調用以前使用setAccessible(true),
Xxx x = getDeclaredXxxx();//才能獲得私有的類字段.
總結步驟:
例子
package junereflect624;
import java.lang.reflect.Constructor;
class Per{
private String name;
private int age;
private Per(){
}
private Per(String name){
}
public String toString() {
return "對象!!!";
}
}
public class NewInstanceDemo7 {
public static void main(String[] args) throws Exception {
Class<Per> c = Per.class;
//System.out.println(c.newInstance());;//證實利用無參的能夠
////先得到須要被調用的構造器(private 修飾的構造方法)
Constructor<Per> con = c.getDeclaredConstructor();//調用默認的,什麼都不要寫
System.out.println(con);//private junereflect624.Per()
/*con = c.getDeclaredConstructor(String.class);獲取指定的構造方法
System.out.println(con);//private junereflect624.Per(java.lang.String)*/
//如今只須要執行這個構造器,
/**
* T newInstance(Object... initargs)
使用此 Constructor 對象表示的構造方法來建立該構造方法的聲明類的新實例,並用指定的初始化參數初始化該實例。
*/
//私有的成員是受保護的,不能直接訪問
//若要訪問私有的成員,得先申請一下
con.setAccessible(true);//容許訪問
Per p = con.newInstance();//成功,經過私有的受保護的構造方法建立了對象
System.out.println("無參構造方法"+p);
con = c.getDeclaredConstructor(String.class);
System.out.println(con);//private junereflect624.Per(java.lang.String)
con.setAccessible(true);//容許訪問
p = con.newInstance("liuzhao");//成功,經過私有的受保護的構造方法建立了對象
System.out.println("String構造方法"+p);
}
}
備註:對於此時的話,單例模式就再也不安全了!反射可破之!!
驗證:對於枚舉而言,反射依然沒有辦法從新建立對象
對於枚舉,安全!
package junereflect624;
import java.lang.reflect.Constructor;
enum Color{
RED,BLUE,GREEN;
private Color(){
}
}
public class EnumDemo8 {
public static void main(String[] args) throws Exception {
Class<Color> c = Color.class;
Constructor<Color> con = c.getDeclaredConstructor();//(錯誤在這一行發生,就是說對枚舉而言這種方法連構造器都得到不了,)編譯能夠經過,可是運行就通不過了!
Color co = (Color) con.newInstance();
System.out.println(co);//失敗,證實對枚舉而言不行,因此枚舉的單例模式更加安全
System.out.println(c.isEnum());//true是枚舉
}
}