你需要理解的 Java 反射機制知識總結

  反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。【翻譯於 官方文檔】

  本篇將從以下幾個方面講述反射的知識:

  class 的使用

  方法的反射

  構造函數的反射

  成員變量的反射

  一、什麼是class類

  在面向對象的世界裏,萬物皆對象。類是對象,類是java.lang.Class類的實例對象。另外class類只有java虛擬機才能new出來。任何一個類都是Class 類的實例對象。這實例對象有三種表達方式:

  public class User{

  }public class ClassTest{User u=new User(); //方式1:

  Class c1=User.class;//方式2:Class c2=u.getClass();//方式3:Class c3=Class.forName(com.forezp.User);//可以通過類的類型創建該類的實例對象User user=(User)c1.newInstance();

  }

  二、class類的動態加載

  Class.forName(類的全稱);該方法不僅表示了類的類型,還代表了動態加載類。編譯時刻加載類是靜態加載、運行時刻加載類是動態加載類。

  三、獲取方法信息

  基本的數據類型,void關鍵字都Class 類的實例;可以通過getame();getSimpleName()獲取類的名稱。

  Class c1=String.class;Class c2=int.class;Class c3=void.class;System.out.println(c1.getName());System.out.println(c2.getSimpleName());

  獲取類的所有方法,並打印出來:

  public static void printClassInfo(Object object){

  Class c=object.getClass();

  System.out.println(類的名稱:+c.getName()); /**

  * 一個成員方法就是一個method對象

  * getMethod()所有的 public方法,包括父類繼承的 public

  * getDeclaredMethods()獲取該類所有的方法,包括private ,但不包括繼承的方法。

  */

  Method[] methods=c.getMethods();//獲取方法

  //獲取所以的方法,包括private ,c.getDeclaredMethods();

  for(int i=0;imethods.length;i++){ p= 得到方法的返回類型=

  Class returnType=methods[i].getReturnType();

  System.out.print(returnType.getName()); //得到方法名:

  System.out.print(methods[i].getName()+();

  Class[] parameterTypes=methods[i].getParameterTypes(); for(Class class1:parameterTypes){

  System.out.print(class1.getName()+,);

  }

  System.out.println());

  }

  }

  public class ReflectTest { public static void main(String[] args){

  String s=ss;

  ClassUtil.printClassInfo(s);

  }

  }

  運行:

  類的名稱:java.lang.String

  booleanequals(java.lang.Object,)

  java.lang.StringtoString()

  inthashCode()

  …

  四、獲取成員變量的信息

  也可以獲取類的成員變量信息

  public static void printFiledInfo(Object o){ Class c=o.getClass(); /**

  * getFileds()獲取public

  * getDeclaredFields()獲取所有

  */

  Field[] fileds=c.getDeclaredFields(); for(Field f:fileds){ //獲取成員變量的類型

  Class filedType=f.getType(); System.out.println(filedType.getName()+ +f.getName());

  }

  }

  public static void main(String[] args){

  String s=ss; //ClassUtil.printClassInfo(s);

  ClassUtil.printFiledInfo(s);

  }

  運行:

  [C value

  int hash

  long serialVersionUID

  [Ljava.io.ObjectStreamField; serialPersistentFields

  java.util.Comparator CASE_INSENSITIVE_ORDER

  int HASHING_SEED

  int hash32

  五、獲取構造函數的信息

  public static void printConstructInfo(Object o){ Class c=o.getClass(); Constructor[] constructors=c.getDeclaredConstructors(); for (Constructor con:constructors){ System.out.print(con.getName()+”(“); Class[] typeParas=con.getParameterTypes(); for (Class class1:typeParas){ System.out.print(class1.getName()+” ,”);

  } System.out.println(“)”);

  }

  }

  public static void main(String[] args){

  String s=ss; //ClassUtil.printClassInfo(s);

  //ClassUtil.printFiledInfo(s);

  ClassUtil.printConstructInfo(s);

  }

  運行:

  java.lang.String([B ,)

  java.lang.String([B ,int ,int ,)

  java.lang.String([B ,java.nio.charset.Charset ,)

  java.lang.String([B ,java.lang.String ,)

  java.lang.String([B ,int ,int ,java.nio.charset.Charset ,)

  java.lang.String(int ,int ,[C ,)

  java.lang.String([C ,boolean ,)

  java.lang.String(java.lang.StringBuilder ,)

  java.lang.String(java.lang.StringBuffer ,)

  ...

  六、方法反射的操作

  獲取一個方法:需要獲取方法的名稱和方法的參數才能決定一個方法。

  方法的反射操作:

  method.invoke(對象,參數列表);

  舉個例子:

  class A{ public void add(int a,int b){

  System.out.print(a+b);

  } public void toUpper(String a){

  System.out.print(a.toUpperCase());

  }

  }

  public static void main(String[] args) {

  A a=new A();

  Class c=a.getClass(); try {

  Method method=c.getMethod(add,new Class[]{int.class,int.class}); //也可以 Method method=c.getMethod(add,int.class,int.class);

  //方法的反射操作

  method.invoke(a,10,10);

  }catch (Exception e){

  e.printStackTrace();

  }

  }

  運行:

  20

  本篇文章已經講解了java反射的基本用法, 它可以在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章