Java 反射学习

Android中有些方法是不能调用的,因为没有对外提供使用权限,这时候可以用反射来实现

一.场景

 

   
   
   
   
  1. try { 
  2.             // 获取系统电话管理的服务  
  3.             Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class); 
  4.             IBinder binder = (IBinder)method.invoke(null, new Object[]{TELEPHONY_SERVICE}); 
  5.             iTelephony =    ITelephony.Stub.asInterface(binder); 
  6.         } catch (Exception e) { 
  7.             // TODO Auto-generated catch block 
  8.             e.printStackTrace(); 

        } 

可以改为


   
   
   
   
  1. //1.获取类 
  2. Class clazz =Class.forName("android.os.ServiceManager"); 
  3. //2.通过类获取方法 
  4. Method method =clazz.getMethod("getService", String.class); 
  5. //3.调用获取的方法,取得返回值(method的作用对象为空,可以看出getService在源码中是一个静态方法) 
  6.  IBinder binder =(IBinder)method.invoke(null, new Object[]{TELEPHONY_SERVICE}); 
  7.          iTelephony =   ITelephony.Stub.asInterface(binder); 
  8.   

 

二.什么是反射?

一句话:反射就是把java类中的各种成分映射成为相应的java类

Java类编译后变成了.class 二进制字节文件,将这些加载jvm中二进制字节文件映射成为对应的类就是反射

 

三、为什么要用反射?

1.实现框架功能 :通过配置文件调用类(Properties类)

2.Android中某些系统类没有对外提供使用权限,比如文章开头中的场景提到的代码,我们无法通过类名直接实例化出对象,然后拿着对象.方法(),这时候也可以使用反射

 

 

 

 

3.1反射的使用代码案例

 

   
   
   
   
  1. /首先根据包名 获取对应类的Class实例 
  2.         Class clazz = Class.forName("com.vincent.java.entity.Person"); 
  3.  
  4.  
  5.         /** 
  6.          * 0.通过无参构造函数实例化对象 
  7.          */ 
  8.         Person p =(Person)clazz.newInstance(); 
  9.  
  10.         //p.sayHello(); 
  11.  
  12.         /** 
  13.          *  
  14.          *  
  15.          * 1.通过Constructor实例实例化对象 
  16.          *  
  17.          * 有参构造函数实例化对象()---getConstructor(参数1类型.class,参数2类型.class) 
  18.          */ 
  19.         Constructor con =clazz.getConstructor(int.class,String.class); 
  20.  
  21.         Person p2 = (Person) con.newInstance(12,"dxx"); 
  22.  
  23.         System.out.println(p2.toString()); 
  24.  
  25.         /** 
  26.          * 2.使用Field获取成员变量 
  27.          *  
  28.          * class.getFeild("变量名字"); 
  29.          * fild.set(作用对象,变量修的新值); 
  30.          */ 
  31.  
  32.         Field  x = clazz.getField("name"); 
  33.         x.set(p2, "dongxiangxiagn"); 
  34.  
  35.         System.out.println(p2.toString()); 
  36.  
  37.         /** 
  38.          * 3.调用方法 
  39.          */ 
  40.         //- 通过getMethod(方法名字,参数类型.class)获得方法对应的Method实例 
  41.         //- 通过method的invoke(方法作用对象,new Object[]{参数值1,参数值2...})来调用方法 
  42.  
  43.         //调用无参方法 sayHello(); 
  44.         Method method_void =clazz.getMethod("sayHello", null); 
  45.         method_void.invoke(clazz.newInstance(), null); 
  46.  
  47.         //调用有参方法 sayHello(String str); 
  48.         Method method =clazz.getMethod("sayHello", String.class); 
  49.         method.invoke(clazz.newInstance(), new Object[]{"vincent"}); 
  50.  
  51.         //调用静态方法  sayStaticHello(); 
  52.         //静态方法invoke时候的最用对象处,传入null即可 
  53.         Method method_static  = clazz.getMethod("sayStaticHello", null); 
  54.         method_static.invoke(null, null); 
  55.  
  56.          
  57.         //调用带返回值的多参方法   float subXAndY(float x,float y); 
  58.         Method method_sub = clazz.getMethod("subXAndY", float.class,float.class); 
  59.          
  60.         Float result = (Float) method_sub.invoke(null, new Object[]{2.0f,100.0f}); 
  61.         System.out.print("The sub result is :"+result); 
  62.  
  63.         /** 
  64.          * 4.调用String的char方法 
  65.          */ 
  66.         String charStr = "abc"
  67.  
  68.         Class class_Char = Class.forName("java.lang.String"); 
  69.  
  70.         Method mehtod_charAt = class_Char.getMethod("charAt", int.class); 
  71.  
  72.         System.out.println(mehtod_charAt.invoke(charStr, 2)); 

 

3.2关于数组反射的使用案例

 

   
   
   
   
  1. //获取Class类对象 
  2.         Class clazz = obj.getClass(); 
  3.          
  4.         if (clazz.isArray()) {// 判断是否是数组 
  5.  
  6.             System.out.println("YES,传入的对象是数组,开始打印"); 
  7.  
  8.             /** 
  9.              * Array 类提供了动态创建和访问 Java 数组的方法。 
  10.              *  
  11.              * Array 允许在执行 get 或 set 操作期间进行扩展转换 
  12.              *  
  13.              */ 
  14.             int length = Array.getLength(obj); 
  15.             for (int i = 0; i < length; i++) { 
  16.  
  17.                 System.out.println(Array.get(obj, i)); 
  18.             } 
  19.  
  20.         } else { 
  21.  
  22.             System.out.println("NO,传入的对象不是是数组,开始打印"); 
  23.  
  24.             System.out.println(obj); 
  25.         } 

四.关于Class的实验 

 通过 1.对象.getClass( )方法  2.类名.class  3.Class.forName(包名.类名)

三种方法得出的Class对象都是同一个对象

 

Java反射学习_第1张图片