1. 程式人生 > >Java中反射機制(Reflection)研究及原始碼演示

Java中反射機制(Reflection)研究及原始碼演示

如下內容內容是關於 Java中反射機制(Reflection)研究及演示的內容。

 

package com.jiangqq.reflection;
import java.lang.reflect.Method;
public class Reflection1 {
public static void main(String[] args) throws Exception {
Class<?> tClass = Class.forName("java.lang.Class");
Method[] methods = tClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}




(三)檢視Class的API發現Class類是ReflectionAPI中的核心類,它有以下幾個常用的方法①:getName():獲得類的完整名字。②:getFields():獲得類的public型別的屬性。③:getDeclaredFields():獲得類的所有屬性。④:getMethods():獲得類的public型別的方法。⑤:getDeclaredMethods():獲得類的所有方法。⑥:getMethod(Stringname,Class[]parameterTypes):獲得類的特定方法,name引數指定方法的名字parameterTypes引數指定方法的引數型別。⑦:getConstructors():獲得類的public型別的構造方法。⑧:getConstructor(Class[]parameterTypes):獲得類的特定構造方法,parameterTypes引數指定構造方法的引數型別。⑨:newInstance():通過類的不帶引數的構造方法建立這個類的一個物件。先看上面的⑧和⑨其中都能生成物件,但是因為建構函式有無參和有參建構函式兩種,所以我們分兩種情況考慮情況一:如果是無參的建構函式來生成物件:<a>首先我們去獲取Class物件,然後直接通過Class物件去呼叫newInstance()方法就可以



Class<?> tclass = Reflection2.class;
Object reflection2 = classType.newInstance();

 




首先我們也是去獲取Class物件,然後去去呼叫getConstructor()得到Constructor物件,接著直接呼叫newInstance()即可


 

Class<?> classType = Reflection2.class;
t reflection2 = classType.newInstance();
Constructor<?> constructor = classType.getConstructor(new Class[] {});
reflection2 = constructor.newInstance(new Object[] {});

 




情況二:現在是有參建構函式,那我們只有一種方法來通過反射生成物件:



Class<?> tClass = Person.class;
Constructor cons = classType.getConstructor(new Class[]{String.class, int.class});
Object obj = cons.newInstance(new Object[]{“zhangsan”, 19});





接下來根據以上的一些常用的方法,使用反射舉幾個例子(使用反射來訪問類中的方法):



package com.jiangqq.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Reflection2 {
public int sum(int a, int b) {
return a + b;
}
public String addStr(String str) {
return "This is the:" + str;
}
public static void main(String[] args) throws Exception {
Class<?> classType = Reflection2.class;
Constructor<?> constructor = classType.getConstructor(new Class[] {});
Object reflection2 = constructor.newInstance(new Object[] {});
Method sumMethod = classType.getMethod("sum", new Class[] { int.class,
int.class });
Object result1 = sumMethod.invoke(reflection2, new Object[] { 6, 10 });
System.out.println((Integer) result1);
Method addStrMethod = classType.getMethod("addStr",
new Class[] { String.class });
Object result2 = addStrMethod.invoke(reflection2,
new Object[] { "tom" });
System.out.println((String) result2);
}
}





④:通過反射機制呼叫物件的私有方法,訪問物件的私有變數....我們大家都知道,在Java語言中,如果我們對某些變數,或者方法進行private的宣告,然後我們在其他類中進行不能去呼叫這些方法和變數,但是通過反射機制,這些私有宣告將不復存在【提醒一點:在寫程式的時候,我們最好不要故意經常去使用反射機制來打破這種私有保護...】要實現這種功能,我們需要用到AccessibleObject類中的publicvoidsetAccessible(booleanflag)方法:使用這個方法,把引數flag設定成true,然後我們的field或者method就可以繞過Java語言的語法訪問的檢查具體使用如下:<a>使用反射去訪問私有方法



package com.jiangqq.reflection;
public class Test01 {
private String getName(String name) {
return "This i:" + name;
}
}


package com.jiangqq.reflection;
import java.lang.reflect.Method;
public class TestPrivate01 {
public static void main(String[] args) throws Exception {
Test01 p = new Test01();
Class<?> classType = p.getClass();
Method method = classType.getDeclaredMethod("getName",
new Class[] { String.class });
method.setAccessible(true);
Object object = method.invoke(p, new Object[] { "tom" });
System.out.println((String)object);
}
}

 





使用反射機制去訪問私有變數:


 

package com.jiangqq.reflection;
public class Test02 {
private String name="張三";
private String getName()
{
return name;
}
}


package com.jiangqq.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestPrivate02 {
public static void main(String[] args) throws Exception {
Test02 p = new Test02();
Class<?> classType = p.getClass();
Field field = classType.getDeclaredField("name");
field.setAccessible(true);
field.set(p, "李四");
Method method = classType.getDeclaredMethod("getName", new Class[] {});
method.setAccessible(true);
Object object = method.invoke(p, new Object[] {});
System.out.println((String) object);
}
}