zoukankan      html  css  js  c++  java
  • [转]Android 中利用反射技术实现加减乘除

    本文转自:http://www.cnblogs.com/TerryBlog/archive/2010/08/17/1801559.html

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

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

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

    运行效果如下:

    下面给出全部页面代码:

    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.classint.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.classint.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.classint.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.classint.class });
                Object result 
    = execMthod.invoke(invokeOperation, new Object[] {
                        
    new Integer(first), new Integer(second) });
                
    return result.toString();
            }
            
    return "";
        }
    }

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

  • 相关阅读:
    发送邮件失败Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 535
    文件上传报错:Current request is not a multipart request
    Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.
    IDEA——错误: 找不到或无法加载主类 com.Main
    浅识微服务架构
    ConcurrentHashMap底层实现原理(JDK1.8)源码分析
    Tiled Editor 图块的两种导入方式
    TileMap Editer 编辑器工具介绍
    Tiled 地图编辑器使用教程-官方demo
    log4net 基础
  • 原文地址:https://www.cnblogs.com/freeliver54/p/2186501.html
Copyright © 2011-2022 走看看