Java反射机制详解

    xiaoxiao2021-03-25  95

    转自:http://www.cnblogs.com/lzq198754/p/5780331.html java  反射  定义  功能  示例 概要:

    Java反射机制详解

    | |目录

    1反射机制是什么2反射机制能做什么3反射机制的相关API·通过一个对象获得完整的包名和类名·实例化Class类对象·获取一个对象的父类与实现的接口·获取某个类中的全部构造函数 - 详见下例·通过反射机制实例化一个类的对象·获取某个类的全部属性·获取某个类的全部方法·通过反射机制调用某个类的方法·通过反射机制操作某个类的属性·反射机制的动态代理4反射机制的应用实例·在泛型为Integer的ArrayList中存放一个String类型的对象。·通过反射取得并修改数组的信息·通过反射机制修改数组的大小·将反射机制应用于工厂模式

    1反射机制是什么

    反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    2反射机制能做什么

    反射机制主要提供了以下功能: 

    在运行时判断任意一个对象所属的类;

    在运行时构造任意一个类的对象;

    在运行时判断任意一个类所具有的成员变量和方法;

    在运行时调用任意一个对象的方法;

    生成动态代理。

    3反射机制的相关API

    通过一个对象获得完整的包名和类名

    Java |  复制 1 2 3 4 5 6 7 8 package  net.xsoftlab.baike; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          TestReflect testReflect =  new  TestReflect();          System.out.println(testReflect.getClass().getName());          // 结果 net.xsoftlab.baike.TestReflect      } }

    实例化Class类对象

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  net.xsoftlab.baike; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          Class<?> class1 =  null ;          Class<?> class2 =  null ;          Class<?> class3 =  null ;          // 一般采用这种形式          class1 = Class.forName( "net.xsoftlab.baike.TestReflect" );          class2 =  new  TestReflect().getClass();          class3 = TestReflect. class ;          System.out.println( "类名称   "  + class1.getName());          System.out.println( "类名称   "  + class2.getName());          System.out.println( "类名称   "  + class3.getName());      } }

    获取一个对象的父类与实现的接口

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  net.xsoftlab.baike; import  java.io.Serializable; public  class  TestReflect  implements  Serializable {      private  static  final  long  serialVersionUID = -2862585049955236662L;      public  static  void  main(String[] args)  throws  Exception {          Class<?> clazz = Class.forName( "net.xsoftlab.baike.TestReflect" );          // 取得父类          Class<?> parentClass = clazz.getSuperclass();          System.out.println( "clazz的父类为:"  + parentClass.getName());          // clazz的父类为: java.lang.Object          // 获取所有的接口          Class<?> intes[] = clazz.getInterfaces();          System.out.println( "clazz实现的接口有:" );          for  ( int  i =  0 ; i < intes.length; i++) {              System.out.println((i +  1 ) +  ":"  + intes[i].getName());          }          // clazz实现的接口有:          // 1:java.io.Serializable      } }

    获取某个类中的全部构造函数 - 详见下例

    通过反射机制实例化一个类的对象

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 package  net.xsoftlab.baike; import  java.lang.reflect.Constructor; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          Class<?> class1 =  null ;          class1 = Class.forName( "net.xsoftlab.baike.User" );          // 第一种方法,实例化默认构造方法,调用set赋值          User user = (User) class1.newInstance();          user.setAge( 20 );          user.setName( "Rollen" );          System.out.println(user);          // 结果 User [age=20, name=Rollen]          // 第二种方法 取得全部的构造函数 使用构造函数赋值          Constructor<?> cons[] = class1.getConstructors();          // 查看每个构造方法需要的参数          for  ( int  i =  0 ; i < cons.length; i++) {              Class<?> clazzs[] = cons[i].getParameterTypes();              System.out.print( "cons["  + i +  "] (" );              for  ( int  j =  0 ; j < clazzs.length; j++) {                  if  (j == clazzs.length -  1 )                      System.out.print(clazzs[j].getName());                  else                      System.out.print(clazzs[j].getName() +  "," );              }              System.out.println( ")" );          }          // 结果          // cons[0] (java.lang.String)          // cons[1] (int,java.lang.String)          // cons[2] ()          user = (User) cons[ 0 ].newInstance( "Rollen" );          System.out.println(user);          // 结果 User [age=0, name=Rollen]          user = (User) cons[ 1 ].newInstance( 20 ,  "Rollen" );          System.out.println(user);          // 结果 User [age=20, name=Rollen]      } } class  User {      private  int  age;      private  String name;      public  User() {          super ();      }      public  User(String name) {          super ();          this .name = name;      }      public  User( int  age, String name) {          super ();          this .age = age;          this .name = name;      }      public  int  getAge() {          return  age;      }      public  void  setAge( int  age) {          this .age = age;      }      public  String getName() {          return  name;      }      public  void  setName(String name) {          this .name = name;      }      @Override      public  String toString() {          return  "User [age="  + age +  ", name="  + name +  "]" ;      } }

    获取某个类的全部属性

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  net.xsoftlab.baike; import  java.io.Serializable; import  java.lang.reflect.Field; import  java.lang.reflect.Modifier; public  class  TestReflect  implements  Serializable {      private  static  final  long  serialVersionUID = -2862585049955236662L;      public  static  void  main(String[] args)  throws  Exception {          Class<?> clazz = Class.forName( "net.xsoftlab.baike.TestReflect" );          System.out.println( "===============本类属性===============" );          // 取得本类的全部属性          Field[] field = clazz.getDeclaredFields();          for  ( int  i =  0 ; i < field.length; i++) {              // 权限修饰符              int  mo = field[i].getModifiers();              String priv = Modifier.toString(mo);              // 属性类型              Class<?> type = field[i].getType();              System.out.println(priv +  " "  + type.getName() +  " "  + field[i].getName() +  ";" );          }                    System.out.println( "==========实现的接口或者父类的属性==========" );          // 取得实现的接口或者父类的属性          Field[] filed1 = clazz.getFields();          for  ( int  j =  0 ; j < filed1.length; j++) {              // 权限修饰符              int  mo = filed1[j].getModifiers();              String priv = Modifier.toString(mo);              // 属性类型              Class<?> type = filed1[j].getType();              System.out.println(priv +  " "  + type.getName() +  " "  + filed1[j].getName() +  ";" );          }      } }

    获取某个类的全部方法

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package  net.xsoftlab.baike; import  java.io.Serializable; import  java.lang.reflect.Method; import  java.lang.reflect.Modifier; public  class  TestReflect  implements  Serializable {      private  static  final  long  serialVersionUID = -2862585049955236662L;      public  static  void  main(String[] args)  throws  Exception {          Class<?> clazz = Class.forName( "net.xsoftlab.baike.TestReflect" );          Method method[] = clazz.getMethods();          for  ( int  i =  0 ; i < method.length; ++i) {              Class<?> returnType = method[i].getReturnType();              Class<?> para[] = method[i].getParameterTypes();              int  temp = method[i].getModifiers();              System.out.print(Modifier.toString(temp) +  " " );              System.out.print(returnType.getName() +  "  " );              System.out.print(method[i].getName() +  " " );              System.out.print( "(" );              for  ( int  j =  0 ; j < para.length; ++j) {                  System.out.print(para[j].getName() +  " "  +  "arg"  + j);                  if  (j < para.length -  1 ) {                      System.out.print( "," );                  }              }              Class<?> exce[] = method[i].getExceptionTypes();              if  (exce.length >  0 ) {                  System.out.print( ") throws " );                  for  ( int  k =  0 ; k < exce.length; ++k) {                      System.out.print(exce[k].getName() +  " " );                      if  (k < exce.length -  1 ) {                          System.out.print( "," );                      }                  }              }  else  {                  System.out.print( ")" );              }              System.out.println();          }      } }

    通过反射机制调用某个类的方法

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package  net.xsoftlab.baike; import  java.lang.reflect.Method; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          Class<?> clazz = Class.forName( "net.xsoftlab.baike.TestReflect" );          // 调用TestReflect类中的reflect1方法          Method method = clazz.getMethod( "reflect1" );          method.invoke(clazz.newInstance());          // Java 反射机制 - 调用某个类的方法1.          // 调用TestReflect的reflect2方法          method = clazz.getMethod( "reflect2" ,  int . class , String. class );          method.invoke(clazz.newInstance(),  20 ,  "张三" );          // Java 反射机制 - 调用某个类的方法2.          // age -> 20. name -> 张三      }      public  void  reflect1() {          System.out.println( "Java 反射机制 - 调用某个类的方法1." );      }      public  void  reflect2( int  age, String name) {          System.out.println( "Java 反射机制 - 调用某个类的方法2." );          System.out.println( "age -> "  + age +  ". name -> "  + name);      } }

    通过反射机制操作某个类的属性

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package  net.xsoftlab.baike; import  java.lang.reflect.Field; public  class  TestReflect {      private  String proprety =  null ;      public  static  void  main(String[] args)  throws  Exception {          Class<?> clazz = Class.forName( "net.xsoftlab.baike.TestReflect" );          Object obj = clazz.newInstance();          // 可以直接对 private 的属性赋值          Field field = clazz.getDeclaredField( "proprety" );          field.setAccessible( true );          field.set(obj,  "Java反射机制" );          System.out.println(field.get(obj));      } }

    反射机制的动态代理

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 // 获取类加载器的方法 TestReflect testReflect =  new  TestReflect();          System.out.println( "类加载器  "  + testReflect.getClass().getClassLoader().getClass().getName()); package  net.xsoftlab.baike; import  java.lang.reflect.InvocationHandler; import  java.lang.reflect.Method; import  java.lang.reflect.Proxy; //定义项目接口 interface  Subject {      public  String say(String name,  int  age); } // 定义真实项目 class  RealSubject  implements  Subject {      public  String say(String name,  int  age) {          return  name +  "  "  + age;      } } class  MyInvocationHandler  implements  InvocationHandler {      private  Object obj =  null ;      public  Object bind(Object obj) {          this .obj = obj;          return  Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),  this );      }      public  Object invoke(Object proxy, Method method, Object[] args)  throws  Throwable {          Object temp = method.invoke( this .obj, args);          return  temp;      } } /**   * 在java中有三种类类加载器。   *    * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。   *    * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类   *    * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。   *    * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。   *    * @author xsoftlab.net   *    */ public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          MyInvocationHandler demo =  new  MyInvocationHandler();          Subject sub = (Subject) demo.bind( new  RealSubject());          String info = sub.say( "Rollen" ,  20 );          System.out.println(info);      } }

    4反射机制的应用实例

    在泛型为Integer的ArrayList中存放一个String类型的对象。

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 package  net.xsoftlab.baike; import  java.lang.reflect.Method; import  java.util.ArrayList; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          ArrayList<Integer> list =  new  ArrayList<Integer>();          Method method = list.getClass().getMethod( "add" , Object. class );          method.invoke(list,  "Java反射机制实例。" );          System.out.println(list.get( 0 ));      } }

    通过反射取得并修改数组的信息

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 package  net.xsoftlab.baike; import  java.lang.reflect.Array; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          int [] temp = {  1 ,  2 ,  3 ,  4 ,  5  };          Class<?> demo = temp.getClass().getComponentType();          System.out.println( "数组类型: "  + demo.getName());          System.out.println( "数组长度  "  + Array.getLength(temp));          System.out.println( "数组的第一个元素: "  + Array.get(temp,  0 ));          Array.set(temp,  0 ,  100 );          System.out.println( "修改之后数组第一个元素为: "  + Array.get(temp,  0 ));      } }

    通过反射机制修改数组的大小

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package  net.xsoftlab.baike; import  java.lang.reflect.Array; public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          int [] temp = {  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9  };          int [] newTemp = ( int []) arrayInc(temp,  15 );          print(newTemp);          String[] atr = {  "a" ,  "b" ,  "c"  };          String[] str1 = (String[]) arrayInc(atr,  8 );          print(str1);      }      // 修改数组大小      public  static  Object arrayInc(Object obj,  int  len) {          Class<?> arr = obj.getClass().getComponentType();          Object newArr = Array.newInstance(arr, len);          int  co = Array.getLength(obj);          System.arraycopy(obj,  0 , newArr,  0 , co);          return  newArr;      }      // 打印      public  static  void  print(Object obj) {          Class<?> c = obj.getClass();          if  (!c.isArray()) {              return ;          }          System.out.println( "数组长度为: "  + Array.getLength(obj));          for  ( int  i =  0 ; i < Array.getLength(obj); i++) {              System.out.print(Array.get(obj, i) +  " " );          }          System.out.println();      } }

    将反射机制应用于工厂模式

    Java |  复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package  net.xsoftlab.baike; interface  fruit {      public  abstract  void  eat(); } class  Apple  implements  fruit {      public  void  eat() {          System.out.println( "Apple" );      } } class  Orange  implements  fruit {      public  void  eat() {          System.out.println( "Orange" );      } } class  Factory {      public  static  fruit getInstance(String ClassName) {          fruit f =  null ;          try  {              f = (fruit) Class.forName(ClassName).newInstance();          }  catch  (Exception e) {              e.printStackTrace();          }          return  f;      } } /**   * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。   * Java 工厂模式可以参考   * http://baike.xsoftlab.net/view/java-factory-pattern   *    * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。   *    * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。   *    * java 读取 properties 配置文件 的方法可以参考   * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file   *    * @author xsoftlab.net   */ public  class  TestReflect {      public  static  void  main(String[] args)  throws  Exception {          fruit f = Factory.getInstance( "net.xsoftlab.baike.Apple" );          if  (f !=  null ) {              f.eat();          }      } }
    转载请注明原文地址: https://ju.6miu.com/read-10040.html

    最新回复(0)