详解Java编程中的反射在Android开发中的应用

反射定义

“反射”(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为。
为何需要反射

反射带来的好处包括:

  • 在运行时检测对象的类型。
  • 动态构造某个类的对象。
  • 检测类的属性和方法。
  • 任意调用对象的方法。
  • 修改构造函数、方法、属性的可见性。

反射方法Method
getDeclaredMethod方法

声明如下:

public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

解释:

返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定已声明方法。
    1. name : 是一个String,它指定所需方法的简称。
    2. parameterTypes:是一个Class对象的变长数组,它按声明顺序标识该方法的形参类型。

注意:
getDeclaredMethod获取该类声明的public方法或者protected方法,但是不包括继承的方法。
getMethod方法

声明如下:

public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

解释:

返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定公共成员方法。
    1. name : 是一个String,它指定所需方法的简称。
    2. parameterTypes:是一个Class对象的变长数组,它按声明顺序标识该方法的形参类型。

参数解释

name参数就不需要解释了,就是调用类的方法名称。

可能很多同学刚接触这个方法的时候,会对parameterTypes参数产生疑问,例如这个参数为什么是Class泛型变长数组,其实举个例子就很好理解了。

假设我们要反射的方法有4个参数,函数原型如下:

public void printInfo(String str, int iNum, double dNum, long i);

那我们通过返回获取这个Method对象的时候,传的parameterTypes如下所示:

getMethod("printInfo", String.class, int.class, double.class, long.class);

所以,parameterTypes其实就是对方法形参的类型抽象。
invoke方法

声明如下:

public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException

解释:

Method类的invoke(Object obj, Object… args)方法接收的参数必须为对象。其中:
    1. obj : 从中调用底层方法的对象。
    2. args :用于方法调用的参数。

Android 反射应用

我们知道,Android有些类是没有在SDK中开放的,例如你需要获取系统属性,需要调用到SystemProperties类的get方法,但是这个类并没有在SDK中公开,我们可以在Android源码中查看一下这个类:

package android.os;

import java.util.ArrayList;

import android.util.Log;

/**
 * Gives access to the system properties store. The system properties
 * store contains a list of string key-value pairs.
 *
 * {@hide}
 */
public class SystemProperties
{
  // 省略具体实现代码
  /**
 * Get the value for the given key.
 * @return an empty string if the key isn't found
 * @throws IllegalArgumentException if the key exceeds 32 characters
 */
 public static String get(String key) {
  if (key.length() > PROP_NAME_MAX) {
   throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
  }
  return native_get(key);
 }
}

可以看到,这个前面有一个@hide标签,所以这个类是没法直接在代码中调用的。

但是,在Android应用中,很多时候我们需要获取到手机类型属性(ro.product.model)。所以,这个时候,我们就需要在应用层反射SystemProperties类,调用get方法。具体实现源码如下:

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

import android.util.Log;

public class SystemProperties {
 public static String get(String key) {
  String value = "";
  Class<?> cls = null;

  try {
   cls = Class.forName("android.os.SystemProperties");
   Method hideMethod = cls.getMethod("get", String.class);
   Object object = cls.newInstance();
   value = (String) hideMethod.invoke(object, key);
  } catch (ClassNotFoundException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (NoSuchMethodException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (InstantiationException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (IllegalAccessException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (IllegalArgumentException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  } catch (InvocationTargetException e) {
   Log.e("zhengyi.wzy", "get error() ", e);
  }

  return value;
 }

}
(0)

相关推荐

  • 应用Java泛型和反射导出CSV文件的方法

    本文实例讲述了应用Java泛型和反射导出CSV文件的方法.分享给大家供大家参考.具体如下: 项目中有需求要把数据导出为CSV文件,因为不同的类有不同的属性,为了代码简单,应用Java的泛型和反射,写了一个函数,完成导出功能. 复制代码 代码如下: public <T> void saveFile(List<T> list, String outFile) throws IOException {         if (list == null || list.isEmpty())

  • Java反射学习 getClass()函数应用

    Java反射学习 所谓反射,可以理解为在运行时期获取对象类型信息的操作.传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码.严格地说,反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制,但是如果编程语言本身支持反射,那么反射的实现就会方便很多. 1,获得类型类 我们知道在Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类.Object类中包含一个方法名叫getClass,利用这个方

  • java反射应用详细介绍

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 复制代码 代码如下: package Reflect; /** * 通过一个对象获得完整的包名和类名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args)

  • 详解Java反射各种应用

    Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Class对象 构造器 变量 方法 私有变量与私有方法 注解 泛型 数组 本文也将从上面几个方面来介绍Java反射.本文涉及的所有代码均在反射代码 首先放出一个Java类作为反射的研究对象,类的内容如下: public abstract class FatherObject implements Runnable{ public v

  • Java学习之反射机制及应用场景介绍

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框架都或多或少的用到Java的反射机制. 什么是Java反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的以及动态调用对象的方法的功能称为Java的反射机制. 反射机制提供了哪些功能? 在运行时判定

  • 详解Java编程中的反射在Android开发中的应用

    反射定义 "反射"(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为. 为何需要反射 反射带来的好处包括: 在运行时检测对象的类型. 动态构造某个类的对象. 检测类的属性和方法. 任意调用对象的方法. 修改构造函数.方法.属性的可见性. 反射方法Method getDeclaredMethod方法 声明如下: public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

  • 详解Java高级特性之反射

    定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. 用途 在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量.方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法.当然,也不是所有的都适合反射,之前就遇到一个案例,通过反射得到的结果与预期不符.阅读源码发现,经过层层调用后在

  • 详解Java编程中Annotation注解对象的使用方法

    注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据.   1.基本语法 Java SE5内置三种标准注解 @Override:表示当前的方法定义将覆盖超类中的方法.如果你不小心拼写错误,或者方法签名对不上被覆 盖的方法,编译器就会发出错误提示 @Deprecated:如果程序员使用了注解为它的元素,那么编译器就会发出警告信息 @SupperessWarnings:关闭不当的编译器警告信息. Java SE5内置四种元注解 @Targ

  • 举例详解Java编程中HashMap的初始化以及遍历的方法

    一.HashMap的初始化 1.HashMap 初始化的文艺写法    HashMap 是一种常用的数据结构,一般用来做数据字典或者 Hash 查找的容器.普通青年一般会这么初始化: HashMap<String, String> map = new HashMap<String, String>(); map.put("Name", "June"); map.put("QQ", "2572073701"

  • 详解Java编程规约(命名风格、常量定义、代码格式)

    命名风格 1.[强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例: _name / __name / $name / name_ / name$ / name__ 2.[强制]代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式. 说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义.注意,纯拼音命名方式更要避免采用. 正例:renminbi / alibaba / taobao / youku / hangzhou 等国际通用的名称,可视

  • 详解Java编程中对线程的中断处理

    1. 引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时--都需要通过一个线程去取消另一个线程正在执行的任务.Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制. 如果对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此.中断机制是如何工作的?捕获或检测到中断后,是抛出InterruptedException还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.st

  • 详解Java编程中包package的内容与包对象的规范

    包的内容 包的内容应该仔细设计,使其只包含在功能上相关的类和接口.包中的类可以自由地访问该包中其他类的非私有成员,有些类甚至可能有足够的权限去访问其他类的内部细节,为了避免这样的类对类成员进行误操作,我们需要对类成员进行保护.任何没有被声明为private的成员都可以被同一个包中的其他所有类型访问,所以任何不相关的类之间的藕合程度都可能会比我们所期望的程度高. 包还为寻找有用的接口和类的程序员提供了逻辑分组的功能.由不相关的类组成的包使程序员很难分辨出哪些接口和类是有用的,而类的逻辑分组可以帮助

  • 详解Java编程中对象的序列化

    1. 什么是Java对象序列化 Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长.但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象.Java对象序列化就能够帮助我们实现该功能. 使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象.必须注意地是,对象序列化保存的是对象的"状态",

  • 详解Java编程中super关键字的用法

    通过用static来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于C语言中的全局函数和全局变量.但是,并不是说有了这种便利,你便可以随处使用,如果那样的话,你便需要认真考虑一下自己是否在用面向对象的思想编程,自己的程序是否是面向对象的. 好了,现在开始讨论this&super这两个关键字的意义和用法.在Java中,this通常指当前对象,super则指父类的.当你想要引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目的,当

  • 详解Java编程中if...else语句的嵌套写法

    if...else if...else语句 if语句后面可以跟elseif-else语句,这种语句可以检测到多种可能的情况. 使用if,else if,else语句的时候,需要注意下面几点: if语句至多有1个else语句,else语句在所有的elseif语句之后. If语句可以有若干个elseif语句,它们必须在else语句之前. 一旦其中一个else if语句检测为true,其他的else if以及else语句都将跳过执行. 语法 if...else语法格式如下: if(布尔表达式 1){

随机推荐