认识反射机制

    技术2022-05-19  34

    认识Java反射机制

         在正常情况下,必须知道一个类才可以实例化对象,但是在Java中也通过一个对象来找到其所在的类的信息,那么这实际上是Class类的功能。

    Java代码     package zyz.demo;  class X{ };  public class GetClassDemo01{      public static void main(String args[]){          X x = new X() ; // 实例化X类的对象          System.out.println(x.getClass().getName()) ;    // 得到对象所在的类的完整名字      }  };      结果:zyz.demo.X  

     

     

     

     

     

     

    实例化Class类型对象

    实例化Class类型对象的方法有三种:

    第一种:通过forName()方法

    第二种:类.class

    第三种:对象.getClass()

     

    Java代码     package zyz.demo;  class X{  };  public class GetClassDemo02{      public static void main(String args[]){          Class<?> c1 = null ;      // 指定泛型          Class<?> c2 = null ;      // 指定泛型          Class<?> c3 = null ;      // 指定泛型          try{              // 以下的操作形式是在开发中最常用的一种形式              c1 = Class.forName("org.lxh.demo15.getclassdemo.X") ;          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          c2 = new X().getClass() ;   // 通过Object类中的方法实例化          c3 = X.class ;  // 通过类.class实例化          System.out.println("类名称:" + c1.getName());// 得到类的名称          System.out.println("类名称:" + c2.getName());// 得到类的名称          System.out.println("类名称:" + c3.getName());// 得到类的名称      }  };  

     

    一旦可以实例化Class类之后,就可以进行反射的进一步操作。

     

    1、实例化对象

    Java代码     <strong>class Person{      private String name ;   // name属性      private int age ;       // age属性      public void setName(String name){          this.name = name ;      }      public void setAge(int age){          this.age = age ;      }      public String getName(){          return this.name ;      }      public int getAge(){          return this.age ;      }      public String toString(){   // 覆写toString()方法          return "姓名:" + this.name + ",年龄:" + this.age  ;      }  };  public class Demo01{      public static void main(String args[]){          Class<?> c = null ;       // 声明Class对象          try{              c = Class.forName("org.lxh.demo15.instancedemo.Person") ;          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          Person per = null ; // 声明Person对象          try{              per = (Person)c.newInstance() ; // 实例化对象          }catch(Exception e){              e.printStackTrace() ;          }          per.setName("李兴华") ;        // 设置姓名          per.setAge(30) ;                // 设置年龄          System.out.println(per) ;   // 内容输出,调用toString()      }  };  </strong>  

     

     

     

     

     

         通过以上的代码,可以发现,即使不使用关键字new对象也可以进行实例化操作,反射的作用。但是,在使用以上操作的时候有一点必须注意,在操作中类中必须存在无参构造方法。否则无法实例化。

     

         所以说,使用以上的方法实际上还是需要类中构造方法的支持,符合于对象的实例化需求。

    如果要想调用有参,由必须按照以下的步骤进行:

    1、通过Class类中的getConstructors()取得本类中的全部构造方法。

    2、向构造方法中传递一个对象数组进去,里面包含了构造方法中所需的各个参数。

    3、之后通过Constructor实例化对象

    Java代码     package org.lxh.demo15.instancedemo ;  import java.lang.reflect.Constructor ;  // 导入反射机制包  class Person{      private String name ;   // name属性      private int age ;       // age属性      public Person(String name,int age){          this.setName(name) ;          this.setAge(age);      }      public void setName(String name){          this.name = name ;      }      public void setAge(int age){          this.age = age ;      }      public String getName(){          return this.name ;      }      public int getAge(){          return this.age ;      }      public String toString(){   // 覆写toString()方法          return "姓名:" + this.name + ",年龄:" + this.age  ;      }  };  public class InstanceDemo03{      public static void main(String args[]){          Class<?> c = null ;       // 声明Class对象          try{              c = Class.forName("org.lxh.demo15.instancedemo.Person") ;          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          Person per = null ; // 声明Person对象          Constructor<?> cons[] = null ;          cons = c.getConstructors() ;          try{              // 第一个数组              per = (Person)cons[0].newInstance("李兴华",30) ;   // 实例化对象          }catch(Exception e){              e.printStackTrace() ;          }          System.out.println(per) ;   // 内容输出,调用toString()      }  };  

     

     

     

     

         但是,从实际角度看,如果要使用反射进行对象的实例化操作,最好在类中存在无参构造。

     

    2、取得类所实现的全部接口

     

    Java代码     package org.lxh.demo15.classinfodemo ;  public class GetInterfaceDemo{      public static void main(String args[]){          Class<?> c1 = null ;      // 声明Class对象          try{              c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          Class<?> c[] = c1.getInterfaces() ;   // 以数组形式返回实现的全部接口          for(int i=0;i<c.length;i++){              System.out.println("实现的接口名称:" + c[i].getName()) ;   // 输出接口名称          }      }      };  结果:实现的接口名称:org.lxh.demo15.China  

     

    3、取得父类

    Java代码     <strong>package org.lxh.demo15.classinfodemo ;  public class GetSuperClassDemo{      public static void main(String args[]){          Class<?> c1 = null ;      // 声明Class对象          try{              c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          Class<?> c2 = c1.getSuperclass() ;    // 取得父类          System.out.println("父类名称:" + c2.getName()) ;      }  };          结果:父类名称:java.lang.Object  </strong>  

     

     

     

     

    4、取得类中的全部构造方法

     

     

     

    Java代码     package org.lxh.demo15.classinfodemo ;  import java.lang.reflect.Constructor ;  // 导入构造方法的包  public class GetConstructorDemo01{      public static void main(String args[]){          Class<?> c1 = null ;      // 声明Class对象          try{              c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          Constructor<?> con[] = c1.getConstructors() ; // 取得一个类中的全部构造          for(int i=0;i<con.length;i++){              System.out.println("构造方法:" + con[i]) ;   // 输出构造,直接打印          }     }               };     结果:  构造方法:public org.lxh.demo15.Person()  构造方法:public org.lxh.demo15.Person(java.lang.String)  构造方法:public org.lxh.demo15.Person(java.lang.String,int)  

      

     

     

     

         以上的操作确实取得了类中的构造方法,但是此时是通过对象直接打印取得的,肯定会调用Constructor类中的toString()方法。

         Constructor类中存在了以下的几个方法:

        取得修饰符:public int getModifiers()

        取得方法名称:public String getName()

        取得参数的类型:public Class<?>[] getParameterTypes()

    Java代码     package org.lxh.demo15.classinfodemo ;  import java.lang.reflect.Constructor ;  // 导入构造方法的包  public class GetConstructorDemo02{      public static void main(String args[]){          Class<?> c1 = null ;      // 声明Class对象          try{              c1 = Class.forName("org.lxh.demo15.Person") ;   // 实例化对象          }catch(ClassNotFoundException e){              e.printStackTrace() ;          }          Constructor<?> con[] = c1.getConstructors() ; // 取得一个类中的全部构造          for(int i=0;i<con.length;i++){              Class<?> p[] = con[i].getParameterTypes() ;       // 得到构造方法中的全部参数              System.out.print("构造方法:" ) ;     // 输出构造,直接打印              System.out.print(con[i].getModifiers() + " ") ; // 得到修饰符              System.out.print(con[i].getName()) ;    // 取得构造方法的名字              System.out.print("(") ;              for(int j=0;j<p.length;j++){                  System.out.print(p[j].getName() + " arg" + i) ;                  if(j<p.length-1){                      // 判断此是否是最后一个参数                      System.out.print(",");  // 输出“,”                  }              }              System.out.println("){}") ;          }      }  };  


    最新回复(0)