Android开发---Android编程之Java反射

来源:互联网 发布:女留学生遇害 知乎 编辑:程序博客网 时间:2024/06/06 08:37
Android应用开发之反射机制


1.反射机制的定义
1.1 基本定义
    java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的
  任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
      然而在android中Google很多的类的某些方法不让第三方应用去调用,通过java反射机制能把这些隐藏方法获取出来并调用,三方
  应用上我们就很方便的去用这些方法。例如,在Android开发当中杀死某个应用的服务和进程调用ActivityManager.forceStopPackage()
  方法就非常方便。
1.2 具体含义
       如果熟悉Android,那么你应该知道,Google不知出于什么原因,在系统源码中一些类或方法中经常加上“@hide”注释标记。它的作用是使这个方法或类在生成SDK时不可见,因此由此注释的东西,你在编译期是不可见的。这就出现了一些问题。一些明明可以访问的东西编译期却无法访问了!这使得你的程序有些本来可以完成的功能无法编译通过。当然,有一种办法是自己去掉Android源码中的所有“@hide”标记,然后重新编译一份自己的SDK。另一种办法就是使用Java反射机制。

 如果你使用Java,那么你应该知道Java中有一个Class类。Class类本身表示Java对象的类型,我们可以通过一个Object(子)对象的getClass方法取得一个对象的类型,此函数返回的就是一个Class类。当然,获得Class对象的方法有许多,但是没有一种方法是通过Class的构造函数来生成Class对象的。(参考网址:http://www.blogjava.net/zh-weir/archive/2011/03/26/347063.html)

----------------------------------------------------------------------------------------------------------------------------


获取一些基本信息
在我们得到一个类的Class类对象之后,Java反射机制就可以大展拳脚了。
2.Java类反射中所必须的类:
   Java的类反射所需要的类并不多,它们分别是:Field、Constructor、Method、Class、Object。下面,我将对这些类做一个简单的说明。

------------------------------------------------------------------------------------------------------------------------------

  Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把 它看成为一个封装反射类的属性的类。
 Constructor类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性。而 Constructor类则封装了反射类的构造方法。
 1) 得到某个类的所有构造方法为:
    Constructor [] constructors = Class.forName("java.lang.String").getConstructors();
  2)   得到某一个构造方法:
    Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
 Method类:提供关于类的接口上单独某个方法的信息。所反映的方法可能是类方法和实例方法(包括抽象方法)。这个类不难理解,它是用来
 封装反射类的方法的一个类。
 Class类:类的实例表示正在运行的java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为Class的一个类,
 所有具有相同元素类型和维数的数组都共享该Class对象。
 Object类:每个类都是使用Object类作为超类。所有对象(包括数组)都实现了这个类的方法。
创建实例对象的方法:
1)通常方式:String str=new String(new StringBuffer("abc"));
2)反射方式:String str=(String) constructor.newInstance(new StringBuffer("abc"));

----------------------------------------------------------------------------------------------------------------------------

代码示例一:

package com.example.reflect;


public class ReflectTest {
    
    public static void main(String[] args) throws Exception{
        String str1="abc";
        Class class1=str1.getClass();
        Class class2=String.class;
        Class class3=Class.forName("java.lang.String");
        System.out.println(class1 == class2);
        System.out.println(class1 == class3);
    }
}
测试结果:
true
true

=================================================================================

3.关于属性Field类的使用举例论证

-----------------------------------------------------------------------------------------------------------------------------------------------

package com.example.reflect;


public class User {
    
    private int width,height;
    private int table=3;
    public int area;
    public String name;
    protected float angle;
    
    public User(int width,int height){
        this.width=width;
        this.height=height;
    }
    
    public int add(int a,int b){
        return a+b;
    }
}


测试代码:
package com.example.reflect;


import java.lang.reflect.Field;


public class ReflectTest {
    
    public static void main(String[] args) throws Exception{
        User user=new User(3,4);
        Class userClass=user.getClass(); //获取到User类的Class对象
        try{
            System.out.println("反射类中类的public类型变量的返回值类型");
            System.out.println("-----------------------");
            Field[] fieldType=userClass.getFields();  //public 类型
            for(int i=0;i<fieldType.length;i++){
                Class fieldClass=fieldType[i].getType();
                System.out.println("返回值:"+fieldClass);
            }
            System.out.println("------------------------");
            
            System.out.println("反射类中类的成员变量的所有属性返回值类型");
            Field[] field=userClass.getDeclaredFields(); //private、protected、public
            for(int i=0;i<field.length;i++){
                Class fieldClass=field[i].getType();
                System.out.println("返回值:"+fieldClass);
            }
            System.out.println("------------------------");
            
            System.out.println("反射类中私有属性的值");
            //获取private类型的变量值
            Field privateField=userClass.getDeclaredField("table"); 
            privateField.setAccessible(true);
            
            Integer i= (Integer)privateField.get(user);
            System.out.println(i);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}


测试结果:
反射类中类的public类型变量的返回值类型
----------------------------------------
返回值:int
返回值:class java.lang.String
----------------------------------------
反射类中类的成员变量的所有属性返回值类型
返回值:int
返回值:int
返回值:int
返回值:int
返回值:class java.lang.String
返回值:float
----------------------------------------
反射类中私有属性的值
table=3

============================================================

4.关于构造方法Constructor类的使用举例

--------------------------------------------------------------------------------------------------------------

package com.example.reflect;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;


public class ReflectTest {
    
    public static void main(String[] args) throws Exception{
        User user=new User(3,4);
        printConstructor(user);
    }
    
    public static void printConstructor(User u){
        Class object=u.getClass(); //获取到Class对象
         //获取指定类的类名称
        String className=object.getName();
        try{
            Constructor[] theConstructors=object.getConstructors();
            for(int i=0;i<theConstructors.length;i++){
                Class[] parameterTypes=theConstructors[i].getParameterTypes();
                System.out.println(className+"(");
                for(int j=0;j<parameterTypes.length;j++){
                    System.out.println(parameterTypes[j].getName()+" ");
                }
                System.out.println(")");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
测试结果如下:
com.example.reflect.User(
int 
int 
)

===========================================================

5.反射类的方法的获取,即Method类的使用:

------------------------------------------------------------------------------------------------------------------------------------------------

一般获取成员方法为:
Method getMethod(String name, Class[] params)
Method[] getMethods()
Method getDeclaredMethod(String name, Class[] params) 
Method[] getDeclaredMethods() 


1、getDeclaredMethods和getMethods的区别
     Method  getDeclaredMethod(String name, Class... parameterTypes) :  Returns a Method object that reflects the specified declared method of the class or interface represented by   this Class object.
    Method[]  getDeclaredMethods() : Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object.


        由此可见,getDeclaredMethod*()获取的是类自身声的所有方法,包含public、protected和private方法。getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。
        注意:因此用反射调用私有方法,必须用getDeclaredMethod方法,同时注意调用私有方法和改变私有变量一样,必须在调用前设置 method.setAccessible(true),这就是传说中的暴力反射吧!另外注意的一点如果是boolean型的参数,得到方法的时候需要用boolean.class或者Boolean.TYPE,不能用Boolean.class。
        得到方法的时候可以用Method.toString()方法,打印出函数的完整原型,如protected java.lang.String com.unity3d.player.UnityPlayer.getCPUType();

---------------------------------------------------------------------------------------------------------------------------------------------------------

代码示例:
package com.example.reflect;


public class User {
    
    private int width,height;
    private int table=3;
    public int area;
    public String name;
    protected float angle;
    
    public User(int width,int height){
        this.width=width;
        this.height=height;
    }
    
    private int add(int a,int b){
        return a+b;
    }
}
测试代码:
package com.example.reflect;


import java.lang.reflect.Method;


public class ReflectTest {
    
    public static void main(String[] args) throws Exception{
        User user=new User(3,4);
        printMemberFunction(user);
    }
    
    public static void printMemberFunction(Object user){
        Class object=user.getClass();
         //获取指定类的类名称
        String className=object.getName();
        try{
            //获取方法的转化方法,参数,转化为Method类型
            Method method=object.getDeclaredMethod("add", int.class,int.class);
            //同上面的方法等同
            Method method=object.getDeclaredMethod("add", Integer.TYPE,Integer.TYPE);

            System.out.println(method.toString());
            method.setAccessible(true); //私有方法必须要使用这样一条语句
            int result=(Integer)method.invoke(user, 2,3); //使用反射的方法调用相应的方法
            System.out.println(result); 
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

打印结果为:

private int com.example.reflect.User.add(int,int)
5

--------------------------------------------------------------------------------------------------------------------------------------------------

原创粉丝点击