Java反射之——方法的反射操作
Java反射中 ,方法的反射操作是通過Method物件呼叫invoke(物件,引數)方法,之前我們需要知道怎樣來確定一個方法?
注:通過方法名和引數列表我們可以唯一確定一個方法。
首先我們獲取方法就是獲取類中的資訊,獲取類的資訊需要得到類型別,因此我們通過已知A的例項物件a1,呼叫getClass()方法得到A類型別,然後呼叫getMethod方法獲取到Method物件,然後Method物件呼叫invoke()方法。
整個流程:
一、已知A類,通過例項物件a1獲取類型別
class A{
public void print() {
System.out.println("hello world");
}
public void print(int a, int b) {
System.out.println(a+b);
}
public void print(String a, String b) {
System.out.println(a.toUpperCase()+","+b.toLowerCase());
}
}
TestA a1 = new TestA();
//通過物件獲取類的類型別,可以獲取到類的資訊
Class class1 = a1.getClass();
二、獲取Method物件
Method m1 = class1.getMethod("print", int.class, int.class);
原始碼中getMethod(String name, Class<?>... parameterTypes),第一個引數為方法的名稱,第二個是引數列表,在這我們可以通過兩種方法來表示
1、int.class, int.class
2、new Class[]{int.class, int.class}——》陣列的方式
這兩種方式結果都是一樣的。
三、通過Method物件呼叫invoke()方法
原始碼中invoke方法返回值預設是Object,如果通過反射操作的方法有返回值且不是Object,需要進行強制轉換;如果操作的物件沒有返回值型別,則返回null。
程式碼奉上:
/**
* 方法的反射實際應用,即:通過類型別獲取方法物件,再通過方法物件進行反射操作。
* 注:方法的名稱和引數列表唯一確定某一個方法
* method.invoke(物件,引數)
*/
public class MethodReflectDemo {
public static void main(String[] args) {
A a1 = new A();
//通過物件獲取類的類型別,可以獲取到類的資訊
Class class1 = a1.getClass();
//通過方法的名稱和引數列表唯一確定一個方法
try {
//通過getMethod()方法獲取方法物件,在這裡可以通過兩種方法獲取
// Method me = class1.getMethod("print", new Class[]{int.class, int.class});
Method me = class1.getMethod("print", int.class, int.class);
//通過invoke()方法進行方法的反射操作,其是指通過Method物件對方法進行操作
//invoke()其實是有返回值的,當方法如果沒有返回值型別(void)則返回null,如果有返回值型別則返回對應的返回值型別(預設是Object,需要做強制型別轉換)
// Object object = me.invoke(a1, new Object[]{10,20});//傳遞陣列方式
Object object = me.invoke(a1, 10,20);
System.out.println("*************************");
// Method me1 = class1.getMethod("print", new Class[]{String.class, String.class});
Method me1 = class1.getMethod("print", String.class, String.class);
object = me1.invoke(a1, "hello", "WORLD");
System.out.println("*************************");
// Method me2 = class1.getMethod("print", new Class[]{});
Method me2 = class1.getMethod("print");
object = me2.invoke(a1);
System.out.println("*************************");
Method m3 = class1.getMethod("print", String.class);
String s = (String)m3.invoke(a1, "方法的反射操作");
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class A{
public void print() {
System.out.println("hello world");
}
public void print(int a, int b) {
System.out.println(a+b);
}
public void print(String a, String b) {
System.out.println(a.toUpperCase()+","+b.toLowerCase());
}
public String print(String s) {
return s;
}
}
輸出結果:
30
*************************
HELLO,world
*************************
hello world
*************************
方法的反射操作
我們在實際應用中的方法反射操作
一、已知一個實體類,通過屬性名,獲取其屬性值。實現的原理就是:通過字串拼接Javabean中的方法,進行方法反射方法的操作。
已知的實體類UserReflect。
public class UserReflect {
private String name;
private String sex;
private int age;
public UserReflect(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public UserReflect() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
封裝方法反射方法的操作
/**
* 根據物件的屬性名獲取物件的屬性值。
* 我們是通過字串拼接成javaBean裡的get方法名,然後通過方法反射執行方法。
*/
public class ReflectApplyMethod {
public static Object getValueByPropertyName(Object object, String propertyName) {
Object value = null;
//拼接Javabean中的方法,得到方法名
String action = "get"+propertyName.substring(0, 1).toUpperCase()+propertyName.substring(1);
System.out.println("方法名:"+action);
//通過已知物件object得到類型別
Class class1 = object.getClass();
//獲取Method物件,get方法都是public,所有使用getMethod()
try {
Method m = class1.getMethod(action);
value = m.invoke(object);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
public static void main(String[] args) {
//主函式呼叫通過屬性名獲取屬性值的方法
UserReflect uReflect = new UserReflect("Tom", "男", 20);
System.out.println(getValueByPropertyName(uReflect, "name"));
System.out.println(getValueByPropertyName(uReflect, "sex"));
System.out.println(getValueByPropertyName(uReflect, "age"));
}
}
主函式輸出結果:
方法名:getName
Tom
方法名:getSex
男
方法名:getAge
20