JAVA反射机制定义

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

  Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

  有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。

  一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。



  尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

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

以上摘录自百度百科,在Android 中有很多类是被封闭的,比如 ServiceManager 蓝牙模块更是有N多个类被Android 隐藏不开放,要调用这些类必须使用java 的反射技术将类转为对象进行操作.Android 应用也是基于JAVA 语言为基础,当然也具备反射这一技术,下面我写了一个DEMO 是如何通过反射技术调用类名方法并完成一个加减乘除的记算器。

 

首先我们定义一个类,此为只是简单的定义几个方法,即加减乘除四个方法,代码如下:

class 
    operationClass {

     
   public 
     
   float 
    add( 
   int 
    parm1,  
   int 
    parm2) {
         
   return 
    parm1  
   + 
    parm2;
    }

     
   public 
     
   float 
    cut( 
   int 
    parm1,  
   int 
    parm2) {
         
   return 
    parm1  
   - 
    parm2;
    }

     
   public 
     
   float 
    ride( 
   int 
    parm1,  
   int 
    parm2) {
         
   return 
    parm1  
   * 
    parm2;
    }

     
   public 
     
   float 
    Except( 
   int 
    parm1,  
   int 
    parm2) {
         
   return 
    parm1  
   / 
    parm2;
    }
} 
 
 
 
 
 
  
  
界面布局文件代码 
  
<?     xml version="1.0" encoding="utf-8" 
    ?> 
    
     < 
    LinearLayout  
    xmlns:android 
    ="http://schemas.android.com/apk/res/android" 
    
    android:layout_width     ="fill_parent" 
     android:orientation 
    ="vertical" 
    
    android:layout_height     ="fill_parent" 
    > 
    


         < 
    EditText  
    android:id 
    ="@+id/EditText01" 
     android:layout_width 
    ="fill_parent" 
    
        android:layout_height     ="wrap_content" 
    ></ 
    EditText 
    > 
    
         < 
    EditText  
    android:id 
    ="@+id/EditText02" 
     android:layout_width 
    ="fill_parent" 
    
        android:layout_height     ="wrap_content" 
    ></ 
    EditText 
    > 
    
         < 
    TextView  
    android:id 
    ="@+id/TextView01" 
     android:layout_gravity 
    ="center" 
    
        android:layout_width     ="wrap_content" 
     android:layout_height 
    ="wrap_content" 
    ></ 
    TextView 
    > 
    
         < 
    LinearLayout  
    android:id 
    ="@+id/LinearLayout01" 
    
        android:orientation     ="horizontal" 
     android:layout_width 
    ="wrap_content" 
    
        android:layout_height     ="wrap_content" 
    > 
    
             < 
    Button  
    android:text 
    ="+" 
     android:id 
    ="@+id/Button01" 
    
            android:layout_width     ="wrap_content" 
     android:layout_height 
    ="wrap_content" 
    ></ 
    Button 
    > 
    
             < 
    Button  
    android:text 
    ="-" 
     android:id 
    ="@+id/Button02" 
    
            android:layout_width     ="wrap_content" 
     android:layout_height 
    ="wrap_content" 
    ></ 
    Button 
    > 
    
             < 
    Button  
    android:text 
    ="*" 
     android:id 
    ="@+id/Button03" 
    
            android:layout_width     ="wrap_content" 
     android:layout_height 
    ="wrap_content" 
    ></ 
    Button 
    > 
    
             < 
    Button  
    android:text 
    ="/" 
     android:id 
    ="@+id/Button04" 
    
            android:layout_width     ="wrap_content" 
     android:layout_height 
    ="wrap_content" 
    ></ 
    Button 
    > 
    
             < 
    Button  
    android:text 
    ="=" 
     android:id 
    ="@+id/Button05" 
    
            android:layout_width     ="wrap_content" 
     android:layout_height 
    ="wrap_content" 
    ></ 
    Button 
    > 
    
         </ 
    LinearLayout 
    > 
    
     </ 
    LinearLayout 
    > 
      
 
下面就是一些对反射技术的操作代码了,由于本篇是反射机制的入门篇,在此只是通过一个小DEMO 讲解反射的常用的几个方法,这里的流程如下:
• 获取相应的类对象名称

Class      <?> 
      classType  
     = 
      Class.forName( 
     " 
     com.terry.operationClass 
     " 
     );
  如果知道类名并且类名存在于我们工程中,即jar 文件中包含可以使用如下写法

Class      <?> 
      classType  
     = 
      operationClass. 
     class 
     ;
  • 返回本类对象

Object invokeOperation       = 
      classType.newInstance();
  • 根据类对象名称去查找对应的方法

Method addMethod       = 
      classType.getMethod( 
     " 
     add 
     " 
     ,  
     new 
      Class[] {
                          int 
     . 
     class 
     ,  
     int 
     . 
     class 
      });

  •  参数一:代码需要查找类名的方法,参数二:指定查找方法的参数类型
  • 调用查找 到的方法执行此方法的处理
Object result       = 
      addMethod.invoke(invokeOperation,  
     new 
      Object[] {
                          new 
      Integer(first),  
     new 
      Integer(second) });

  •  

通过调用查找到的方法即可实现方法体的功能。

Tip:反射比较耗费系统资源,建议不在不得以的情况下不要用,尤其是在移动设备上这种对资源要求十分苛刻的设备。

运行效果如下:

Android 反选_android

下面给出全部页面代码:

 

package     com.terry;

    import 
    java.lang.reflect.InvocationTargetException;
    import 
    java.lang.reflect.Method;

    import 
    android.app.Activity;
    import 
    android.os.Bundle;
    import 
    android.view.View;
    import 
    android.view.View.OnClickListener;
    import 
    android.widget.Button;
    import 
    android.widget.EditText;
    import 
    android.widget.TextView;

    public 
     
   class 
    OperationActivity  
   extends 
    Activity {
        private 
    EditText one, two;
        private 
    TextView result;
        private 
    Button add, cut, ride, Except, sum;
        int 
    first, second;
    String operaionFun     = 
     
   "" 
   ;

        /** 
    Called when the activity is first created.  
   */ 
   
    @Override
        public 
     
   void 
    onCreate(Bundle savedInstanceState) {
            super 
   .onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findview();
        add.setOnClickListener(click);
        cut.setOnClickListener(click);
        ride.setOnClickListener(click);
        Except.setOnClickListener(click);
        sum.setOnClickListener(click);
    }

        void 
    findview() {
        one     = 
    (EditText) findViewById(R.id.EditText01);
        two     = 
    (EditText) findViewById(R.id.EditText02);
        result     = 
    (TextView) findViewById(R.id.TextView01);
        add     = 
    (Button) findViewById(R.id.Button01);
        cut     = 
    (Button) findViewById(R.id.Button02);
        ride     = 
    (Button) findViewById(R.id.Button03);
        Except     = 
    (Button) findViewById(R.id.Button04);
        sum     = 
    (Button) findViewById(R.id.Button05);
    }

    OnClickListener click     = 
     
   new 
    OnClickListener() {

        @Override
            public 
     
   void 
    onClick(View v) {
                // 
    TODO Auto-generated method stub 
   
                first  
   = 
    Integer.parseInt(one.getText().toString());
            second     = 
    Integer.parseInt(two.getText().toString());
                switch 
    (v.getId()) {
                case 
    R.id.Button01:
                operaionFun     = 
     
   " 
   + 
   " 
   ;
                    break 
   ;

                case 
    R.id.Button02:
                operaionFun     = 
     
   " 
   - 
   " 
   ;
                    break 
   ;
                case 
    R.id.Button03:
                operaionFun     = 
     
   " 
   * 
   " 
   ;
                    break 
   ;
                case 
    R.id.Button04:
                operaionFun     = 
     
   " 
   / 
   " 
   ;
                    break 
   ;
                case 
    R.id.Button05:
                    try 
    {
                    result.setText(operation(operaionFun, first, second));
                }     catch 
    (SecurityException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }     catch 
    (IllegalArgumentException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }     catch 
    (ClassNotFoundException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }     catch 
    (IllegalAccessException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }     catch 
    (InstantiationException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }     catch 
    (NoSuchMethodException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }     catch 
    (InvocationTargetException e) {
                        // 
    TODO Auto-generated catch block 
   
                        e.printStackTrace();
                }
                    break 
   ;
            }
        }
    };

        /** 
   
     * 操作方法
     * 
     *     @param 
    oper
     *     @param 
    first
     *     @param 
    second
     *     @return 
   
     *     @throws 
    ClassNotFoundException
     *     @throws 
    IllegalAccessException
     *     @throws 
    InstantiationException
     *     @throws 
    SecurityException
     *     @throws 
    NoSuchMethodException
     *     @throws 
    IllegalArgumentException
     *     @throws 
    InvocationTargetException
         */ 
   
    String operation(String oper,     int 
    first,  
   int 
    second)
                throws 
    ClassNotFoundException, IllegalAccessException,
            InstantiationException, SecurityException, NoSuchMethodException,
            IllegalArgumentException, InvocationTargetException {
            // 
    获取相应的类对象名称 
   
            Class 
   <?> 
    classType  
   = 
    Class.forName( 
   " 
   com.terry.operationClass 
   " 
   );

            // 
    如果知道类名并且类名存在于我们工程中,即jar 文件中包含可以使用如下写法
            // 
   Class<?> classType = operationClass.class;
            // 
    返回本类对象 
   
            Object invokeOperation  
   = 
    classType.newInstance();

            if 
    (oper.equals( 
   " 
   + 
   " 
   )) {
                // 
    根据类对象名称去查找对应的方法 
   
                Method addMethod  
   = 
    classType.getMethod( 
   " 
   add 
   " 
   ,  
   new 
    Class[] {
                        int 
   . 
   class 
   ,  
   int 
   . 
   class 
    });
                // 
    调用查找 到的方法执行此方法的处理 
   
                Object result  
   = 
    addMethod.invoke(invokeOperation,  
   new 
    Object[] {
                        new 
    Integer(first),  
   new 
    Integer(second) });
                return 
    result.toString();
        }     else 
     
   if 
    (oper.equals( 
   " 
   - 
   " 
   )) {
            Method cutMethod     = 
    classType.getMethod( 
   " 
   cut 
   " 
   ,  
   new 
    Class[] {
                        int 
   . 
   class 
   ,  
   int 
   . 
   class 
    });
            Object result     = 
    cutMethod.invoke(invokeOperation,  
   new 
    Object[] {
                        new 
    Integer(first),  
   new 
    Integer(second) });
                return 
    result.toString();
        }     else 
     
   if 
    (oper.equals( 
   " 
   * 
   " 
   )) {
            Method rideMethod     = 
    classType.getMethod( 
   " 
   ride 
   " 
   ,  
   new 
    Class[] {
                        int 
   . 
   class 
   ,  
   int 
   . 
   class 
    });
            Object result     = 
    rideMethod.invoke(invokeOperation,  
   new 
    Object[] {
                        new 
    Integer(first),  
   new 
    Integer(second) });
                return 
    result.toString();
        }     else 
     
   if 
    (oper.equals( 
   " 
   / 
   " 
   )) {
            Method execMthod     = 
    classType.getMethod( 
   " 
   Except 
   " 
   ,  
   new 
    Class[] {
                        int 
   . 
   class 
   ,  
   int 
   . 
   class 
    });
            Object result     = 
    execMthod.invoke(invokeOperation,  
   new 
    Object[] {
                        new 
    Integer(first),  
   new 
    Integer(second) });
                return 
    result.toString();
        }
            return 
     
   "" 
   ;
    }
}

 

Tip:在JAVA中可以通过main 函数打印,在Android 好像调用会出错。