java-reflect 常用方法说明及实例

Class类的使用  java.lang.Class
1.1在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。
1.2获取Class实例方式

方法1

利用对象调用getClass()方法获取该对象的Class实例;

方法2

使用Class类的静态方法forName(), 用类的名字获取一个Class实例(staticClass forName(String className) Returns the Classobject associated with the class or interface with the given stringname. );

方法3

运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例
在newInstance()调用类中缺省的构造方法 ObjectnewInstance()(可在不知该类的名字的时候,创建这个类的实例) Creates a new instance of the class represented by this Classobject.
在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已被加载到内存,就可以用它来产生该类型的所有对象 [1]

打印类的类信息

      /**
      * 打印类的信息,包含类的成员函、数成员变量
      */
      public static void printClassMessage(Object obj) {
           // 要获取类的信息 首先要获取类的类类型c
           Class c = obj.getClass(); // 传递的是哪个子类的对象 c就是该子类的类类型
           // 获取类的名字
          System. out .println("类的名称是:" + c.getName());
           /*
           * Method类,方法对象 一个成员方法就是一个Method对象
           * getMethod方法()获取所有public的函数,包括父类继承而来的方法。
           * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
           */
          Method[] ms = c.getDeclaredMethods();
           for (Method method : ms) {
               Class returnType = method.getReturnType();// 得到方法的返回值类型的类类型
              System. out .println(returnType.getName() + " ");
              System. out .print(method.getName());// 得到方法名称
              StringBuilder paramStr = new StringBuilder();
               Class[] paramTypes = method.getParameterTypes();// 获取参数类型-->得到的是参数列表的类型的类类型
               if (paramTypes != null && paramTypes. length > 0) {
                   paramStr.append( "(" );
                    for (Class type : paramTypes) {
                        paramStr.append(type.getName() + "," );
                   }
                   paramStr.deleteCharAt(paramStr.length() - 1);
                   paramStr.append( ")" );
              } else {
                   paramStr.append( "()" );
              }
              System. out .println(paramStr.toString());

               /*
               * 成员变量也是对象java.lang.reflect.Field Field类封装了关于成员变量的操作
               * getFields获取所有的public的成员变量的信息 getDeclaredFields()获取该类自己声明的成员变量的信息
               */
              Field[] fs = c.getDeclaredFields();
               if (fs != null && fs. length > 0) {
                    for (Field field : fs) {
                         // 得到成员变量的类型的类类型
                         Class fType = field.getType();
                        System. out .println(fType.getName() + ":" + field.getName());
                   }
              }

               /*
               * 构造函数也是对象 java.lang.Constructor中封装了构造函数的信息
               * c.getDeclaredConstructors() 得到所有自己声明的构造方法
               */
               Constructor[] cs = c.getDeclaredConstructors();
              System. out .println(cs.length );
               if (cs != null && cs. length > 0) {
                   StringBuilder csStr = new StringBuilder();
                    for (Constructor constructor : cs) {
                        csStr.append(constructor.getName());
                        csStr.append( "(" );
                         Class[] ctypes = constructor.getParameterTypes();
                         if (ctypes != null && ctypes.length > 0) {
                              for (Class type : ctypes) {
                                  csStr.append(type.getName() + "," );
                             }
                             csStr.deleteCharAt(csStr.length() - 1);
                        }
                        csStr.append( ")" );
                   }
                   System. out .println(csStr.toString());
              }
          }
     }

1.3方法的反射
  1)如何获取某个方法?
     方法名和方法的参数列表才能唯一的决定某个方法
  2)方法反射的操作
     method.invoke(对象,参数列表)
实例:
public   static  void  main(String[] args) {
            //如何获取指定print方法,1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类对象
           Class c = A.  class ;
            /*
           *2.获取方法 名称和参数列表来决定唯一的方法
           *class...或者 int...等等 代表的意思是需要1个或多个参数,可以传递new Class[]{X,X,X}或者x,x,x这两种类型的参数
           *getMethod获取的是public的方法
           *getDeclaredMethod获取的是自己声明的方法
           */
            try  {
              Method method = c.getDeclaredMethod(  "print" int .  class  ,  int .  class ) ;
              method.invoke(c.newInstance(), 1,1);  //方法的反射操作,通过方法来操作类去执行。
              
              Method method1 = c.getDeclaredMethod(  "print" new  Class[]{String.  class  ,String. class  } ) ;
              method1.invoke(c.newInstance(),  "hello"  , "World"  ); //方法的反射操作,通过方法来操作类去执行。
          }  catch  (Exception e) {
              e.printStackTrace();
          }
     }

class  A {
     
       public   void  print( int  a,  int  b){
          System.  out  .println(a+b);
     }
     
       public   void  print(String a,String b){
          System.  out  .println(a+b);
     }
}

1.4通过反射了解集合泛型的本质
      List a =  new  ArrayList ();
           List b =  new  ArrayList();
          
           Class ca = a.getClass();
           Class cb = b.getClass();
            //看看list集合的类对象是否相同
          System.  out  .println(ca==cb);
            /*
           *返回结果为true,虽然2个集合的泛型不同,但是类的类对象相同
           *也说明Java中集合的泛型,是防止错误输入的只在编译阶段有效,绕过编译就无效了。
           *验证:方法的反射来操作,绕过编译
           */
            try  {
              Method m = cb.getMethod(  "add" , Object. class  );
              m.invoke(b, 100);
              System.  out  .println(b.size());
              System.  out  .println(b);
                for  ( int  i = 0; i < b.size(); i++) {
                   Object obj = b.get(i);
                   System.  out  .println(obj);
              }
          }  catch  (Exception e) {
              e.printStackTrace();
          }

你可能感兴趣的:(java)