萬事萬物皆對(duì)象
在java中類也是對(duì)象拇惋,是Class類的實(shí)例對(duì)象妄呕,這個(gè)對(duì)象稱為該類的類類型
例如:現(xiàn)在有個(gè)類叫SmartTalk
class SmartTalk {
public String name;
public int age;
public void sayHello() {
System.out.println("hello");
}
private void sayHello(String hello){
System.out.println(hello);
}
}
如何去獲取這個(gè)類的類類型呢陶舞?有以下三種方式:
public class ClassDemo {
public static void main(String[] args) {
//第一種方式,說明每一個(gè)類都默認(rèn)含有一個(gè)靜態(tài)的class對(duì)象
Class c1 = SmartTalk.class;
//第二種方式
SmartTalk smartTalk = new SmartTalk();
Class c2 = smartTalk.getClass();
System.out.println(c1 == c2);//true
//第三種方式
Class c3 = null;
try {
c3 = Class.forName("包名+SmartTalk");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(c2 == c3);//true
//通過類類型獲得實(shí)例對(duì)象
try {
SmartTalk smartTalk1 = (SmartTalk) c1.newInstance();
smartTalk1.sayHello();//hello
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
獲取了類類型有什么用處呢?我們可以獲取一個(gè)類的所有信息包括類名绪励,屬性肿孵,方法等,可以通過Field疏魏,Method等類來實(shí)現(xiàn)停做。
public class ClassUtil {
/**
* 打印該類的信息,通過反射機(jī)制,我們可以獲得一個(gè)類的信息
*
* @param object 該類對(duì)象所屬類的信息
*/
public static void printClassInfo(Object object) {
//要獲取類的信息,首先獲取類的類類型
Class c = object.getClass();
c.getName();//類的全稱(包括包名)
System.out.println(c.getName());
Field[] fields = c.getDeclaredFields();//獲取所有該類自己聲明的屬性(實(shí)例域)
for (Field filed : fields) {
Class fc = filed.getType();//獲取屬性類型的類類型
System.out.print(fc.getName()+" ");
System.out.println(filed.getName());
}
Method[] methods = c.getDeclaredMethods();//獲取所有的public方法,包括父類繼承而來的
c.getDeclaredFields();//獲取所有該類自己聲明的方法,不管訪問去權(quán)限,不包含父類的方法
for (Method m : methods) {
Class returnType = m.getReturnType();//得到方法返回值類型的類類型
System.out.print(returnType.getName() + " ");
m.getName();//獲取方法名稱
System.out.print(m.getName() + "(");
Class[] params = m.getParameterTypes();//獲取方法參數(shù)列表中的類的類類型
for (Class param : params) {
System.out.print(param.getName() + ",");
}
System.out.println(")");
}
}
}
當(dāng)然了,我們還可以獲得一個(gè)屬性的或者方法的訪問權(quán)限大莫,通過getModifiers()方法蛉腌。還有許多特性可以在官方文檔里查閱。下面介紹如何通過反射進(jìn)行方法調(diào)用:
public static void main(String[] args) {
...
Class c1 = SmartTalk.class;//獲得類類型
try {
/**
* 訪問共有方法
*/
Method method1 = c1.getMethod("sayHello"/*方法名*/);//獲得Method對(duì)象,或者使用c1.getDeclaredMethod("sayHello")
method1.invoke(c1.newInstance()/*類對(duì)象*/);//方法調(diào)用
/**
* 訪問非共有方法
*/
Method method2 = c1.getDeclaredMethod("sayHello"/*方法名*/,String.class/*參數(shù)類類型*/);//不可使用getMethod(獲取不到對(duì)象,拋出method not found)
method2.setAccessible(true);//調(diào)用私有方法時(shí)需要設(shè)置為true
method2.invoke(c1.newInstance()/*類對(duì)象*/,"hello,SmartTalk"/*參數(shù)對(duì)象*/);//方法調(diào)用
} catch (Exception e) {
e.printStackTrace();
}
}
通過代碼里的注釋烙丛,很清楚的展示出了反射機(jī)制方法調(diào)用的基本流程舅巷,java反射機(jī)制可以獲取正在運(yùn)行的java對(duì)象,改變其屬性和行為河咽,非常的靈活钠右。這是一篇反射機(jī)制的學(xué)習(xí)筆記,如有錯(cuò)誤库北,感謝批評(píng)指正爬舰。