1. Class 類
Class 類用於保存虛擬機運行時的類型信息。創建 Class 類對象的三種方式:
1)getClass()
Employee e = new Employee("Harry Hacker");
Class<?> cl = e.getClass();
2)Class.forName()
try {
Class<?> cl = Class.forName("study.JavaSE.Employee");
System.out.println(cl.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
3)類名.class
Class<?> cl = Employee.class;
2. Class 類的 newInstance() 創建對象
try {
Class<?> cl = Class.forName("study.JavaSE.Employee");
Employee e = (Employee) cl.newInstance();
e.setName("Harry Hacker");
System.out.println(e.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
class 類的 newInstance() 方法調用的是類的無參構造方法
3. 使用 Constructor 類創建對象
try {
Class<?> cl = Class.forName("study.JavaSE.Employee");
Constructor<?> constructor = cl.getConstructor(String.class);
Employee e = (Employee) constructor.newInstance("Harry Hacker");
System.out.println(e.getName());
} catch (Exception e) {
e.printStackTrace();
}
Constructor 類的 newInstance() 方法可以通過類的帶參數的構造方法創建對象。
Class 類的 getFields()、getMethods()、getConstructors() 方法分別返回類提供的 public 域、方法和構造器數組,包括超類的共有成員,而 Class 類的 getDeclaredFields()、getDeclaredMethods()、getDeclaredConstructors() 方法返回類中聲明的全部域、方法和構造器,包括 private 和 protected 成員,但不包過父類的成員。
4. 設置對象屬性值
Manager harry = new Manager("Harry Hacker");
Class<?> cl = harry.getClass();
try {
Field f = cl.getDeclaredField("buddies"); //獲取屬性名爲 buddies 的屬性對象
f.setAccessible(true); //抑制 Java 訪問控制
Object v = f.get(harry); //獲取屬性值
System.out.println(v);
f.set(harry, 1); //設置屬性值
v = f.get(harry);
System.out.println(v);
} catch (Exception e) {
e.printStackTrace();
}
5. 調用方法可以通過 Method 類的 invoke() 方法實現對反射對象的方法調用。
Class<?> cl = Manager.class;
Manager harry = new Manager("Harry Hacker");
try {
Method m = cl.getDeclaredMethod("setBuddies", Integer.class); //獲取方法名爲 setBuddies,參數類型是 Integer 的方法對象
m.invoke(harry, 50); //調用方法,invoke 方法第一個參數表示操作的對象,第二參數表示所調用方法傳入的參數
System.out.println(harry.getBuddies());
m = cl.getDeclaredMethod("getBuddies"); //獲取無參的方法對象
int n = (Integer)m.invoke(harry);
System.out.println(n);
m = cl.getDeclaredMethod("printStaticMethod");
m.invoke(null); //調用靜態方法
m = cl.getDeclaredMethod("printStaticMethod", String.class);
m.invoke(null, ""); //調用帶參數的靜態方法
} catch (Exception e) {
e.printStackTrace();
}
6. 反射泛型數組
java.lang.reflect 包中的 Array 類 newInstance() 方法可以動態的創建數組。java.utils 包下的 Arrays 類的 copyOf() 方法實現就是應用了 Array.newInstance() 方法。
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
7. 反射應用實例
import java.lang.reflect.Field;
public class BasicModel {
private static String getString(Object o, Class< ? > c){
String res = "";
Field[] fields = c.getDeclaredFields();
if(c.getSuperclass() != BasicModel.class){
res += getString(o, c.getSuperclass()) + ", ";
}
for(Field field : fields){
field.setAccessible(true);
try {
res += field.getName() + " = " + field.get(o) + ", ";
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return res.substring(0, (res.length() - 2 < 0 ? 0 : res.length() - 2));
}
public String toString(){
return BasicModel.getString(this, this.getClass());
}
}