Java反射機制demo(二)—通過Class實例化任意類的對象
上一章節中,實例化了Class類對象的實例,這個部分的demo展示了如何使用Class對象的實例去獲得其他類的對象的實例。
任意一個類,UserInfo,
1 package com.aaron.reflect; 2 3 public class UserInfo{ 4 private int userId; 5 private String name; 6 private int age; 7 8 public int getUserId() { 9 return userId; 10 } 11 public void setUserId(int userId) { 12 this.userId = userId; 13 } 14 public String getName() { 15 return name; 16 } 17 public void setName(String name) { 18 this.name = name; 19 } 20 public int getAge() { 21 return age; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 } 26 @Override 27 public String toString() { 28 return "UserInfo [userId=" + userId + ", name=" + name + ", age=" + age + "]"; 29 } 30 31 } 32
使用newInstance方法,通過調用默認的無參構造來實例化一個UserInfo的對象
1 package com.aaron.reflect; 2 3 public class Demo1 { 4 public static void main(String[] args) { 5 Class<?> c = UserInfo.class;//獲得Class類實例 6 UserInfo userInfo = null; 7 8 try { 9 userInfo = (UserInfo) c.newInstance();//通過Class類的實例獲得UserInfo的實例 10 } catch (InstantiationException e) { 11 e.printStackTrace(); 12 } catch (IllegalAccessException e) { 13 e.printStackTrace(); 14 } 15 16 userInfo.setUserId(1); 17 userInfo.setName("Squee,Spleen and Goblin"); 18 userInfo.setAge(10); 19 20 System.out.println(userInfo); 21 } 22 } 23
如果了解Java虛擬機,應該知道,一個對象在new之前,堆里是不會分配內存的。因此這個UserInfo的實例是通過Class的實例得到的。
運行結果:
UserInfo [userId=1, name=Squee,Spleen and Goblin, age=10]
注意事項:
newInstance()調用的是無參的空構造,如果只有參數的構造函數:如下:
private int userId; private String name; private int age; public UserInfo(int userId, String name, int age) { super(); this.userId = userId; this.name = name; this.age = age; }
運行Demo,拋出異常:
java.lang.InstantiationException: com.aaron.reflect.UserInfo at java.lang.Class.newInstance(Class.java:359) at com.aaron.reflect.Demo1.main(Demo1.java:9) Exception in thread "main" java.lang.NullPointerException at com.aaron.reflect.Demo1.main(Demo1.java:16
此時,要定義一個空的構造函數(顯式地聲明一個空的構造函數)。
所以,顯式聲明空的構造函數有時候也是一種很好的習慣。當你要使用反射時,一定不要忘記空的構造。