package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/**
* 使用反射機制來創建對象
*
* @author lxf
* @time 2014-4-8下午05:08:41
*
*/
public class CreateObject {
/**
* Java的反射機制是指:反射就是把Java類中的各種成分映射成相應相應的Java類, 然後就可以獲取這個類的所有信息
*
* @throws Exception
*/
public static void createObj1() throws Exception {
// 返回與帶有給定字符串名的類或接口相關聯的 Class 對象。
// Class classType = Person.class;
Class classType = Class.forName("test.Person");
Object obj = classType.newInstance();
System.out.println("使用反射反射機制創建出來的對象是否是Person類的對象:"
+ (obj instanceof Person));
}
/**
* 創建帶有構造參數的對象的時候我們需要使用另外一種方式即: 1.先獲取操作類的Class對象即字節碼文件
* 2.使用Class對象的getConstructor
* (parameterTypes)方法獲取該對象的構造方法的對象,注意括號中可以帶不等的可變參數,
* 3.使用構造方法對象的newInstance(initargs)方法就可以實例化一個對象 4.注意,使用這些方法都不可以訪問被
* private修飾的方法,需要設置某些訪問權限setAccessable()方法
*
* @throws Exception
*/
public static void createObj2() throws Exception {
@SuppressWarnings("rawtypes")
Class classType = Person.class;
@SuppressWarnings("unchecked")
Constructor<Person> con = classType.getConstructor(String.class,
int.class);
Object obj = con.newInstance("test", 23);
System.out.println("使用constructor對象的newInstance方法創建對象的信息:"
+ ((Person) obj).getName());
}
/**
* 操作方法包括(private方法) 步驟: 1.首先獲取要操作類的Class對象
* 2.然後通過Class對象的getMethod方法獲取要操作的方法的Method對象(兩個參數,第一個參數是方法名,第二個參數是參數類型)
* 3.調用Method的方法的invoke方法(兩個參數,第一個參數是該方法屬於的類對象,具體參數)
* 4.當方法被private修飾的時候,首先需要調用getDeclaredMethod()方法獲取要操作的被private修飾的類。
* 在這裡要注意這個getDeclaredMethod方法,它既可以用作獲取普通方法的對象也可以用來操作private修飾的方法,
* 但是操作private修飾的方法的時候,必須使用這個方法,其它方法不可以。普通方法還可以使用getMethod方法,
* 且屬性操作也是如此。另外,還需要設置訪問權限setAccessable(true)才可以
*
* @throws Exception
*/
public static void methodDo() throws Exception {
Person p = new Person();
Class classType = Person.class;
Method method = classType.getMethod("setName", String.class);
method.invoke(p, "ckl");
System.out.println("使用反射操作SetName方法後,Person對象的name值是:" + p.getName());
Method method2 = classType.getDeclaredMethod("test");
method2.setAccessible(true);
method2.invoke(p);
}
/**
* 操作字段
*
* @throws Exception
*/
public static void FieldDo() throws Exception {
Person p = new Person();
Class classType = Person.class;
Field field = classType.getDeclaredField("name");
Field field2 = classType.getDeclaredField("age");
field.setAccessible(true);
field2.setAccessible(true);
field.set(p, "test");
field2.set(p, 23);
System.out.println("使用反射機制操作被private修飾的對象字段後得到的屬性值是:" + p.getName());
System.out.println("使用反射機制操作被private修飾的對象字段後得到的屬性值是:" + p.getAge());
}
public static void main(String[] args) throws Exception {
new CreateObject().FieldDo();
}
}
根據以上代碼:.使用反射機制創建對象的步驟如下:
1、先聲明你要創建的對象的類全稱;使用Class類的靜態方法forName(String.className)加載這個類的字節碼(注意,加載字節碼不等於實例化對象) ,返回 一個Class對象,這個對象代表的是一個字節碼文件。
2、調用這個類對象(字節碼)的方法newInstance()方法(注意:這裡的這個newInstance方法默認調用默認的構造方法即調用無參的構造方法, 一旦構造方法有參數時,此方法行不通,需要使用構造方法的對象的相關方法來 實例化)實例化類Person,返回的是Object類型
3、強制轉換成Person類型即你所需類型
而獲得Class對象的方法還有:
Class c = Class.forName("java.lang.String");這條語句得到一個 String 類的類對象。還有另一種方法,如下面的語句:Class c = int.class; 或者 Class c = Integer.TYPE;它們可獲得基本類型的類信息。其中後一種方法中訪問的是基本類型的封裝類 (如 Integer) 中預先定義好的 TYPE 字段。