什么是反射?


反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性 简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。 反射的核心是 JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。 Java 反射主要提供以下功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
  • 在运行时调用任意一个对象的方法 重点:是运行时而不是编译时

反射的运用


获得 Class 对象


  • 使用 Class 类的 forName 静态方法
public static Class<?> forName(String className)
  • 直接获取某一个对象的 class
Class<?> klass = int.class;
Class<?> classInt = Integer.TYPE;
  • 调用某个对象的 getClass() 方法
StringBuilder str = new StringBuilder("123");
Class<?> klass = str.getClass();

判断是否为某个类的实例

一般地,我们用 instanceof 关键字来判断是否为某个类的实例。同时我们也可以借助反射中 Class 对象的 isInstance() 方法来判断是否为某个类的实例,它是一个 native 方法:

public native boolean isInstance(Object obj);

创建实例

通过反射来生成对象主要有两种方式。

  • 使用Class对象的newInstance()方法来创建Class对象对应类的实例。
Class<?> c = String.class;
Object str = c.newInstance();
  • 先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。
//获取String所对应的Class对象
Class<?> c = String.class;
//获取String类带一个String参数的构造器
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance("23333");
System.out.println(obj);

获取构造器信息

得到构造器的方法

Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,
Constructor[] getConstructors() -- 获得类的所有公共构造函数
Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)
Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)

获取类构造器的用法与上述获取方法的用法类似。主要是通过Class类的getConstructor方法得到Constructor类的一个实例,而Constructor类有一个newInstance方法可以创建一个对象实例:

public T newInstance(Object ... initargs)

获取类的成员变量(字段)信息

获得字段信息的方法

Field getField(String name) -- 获得命名的公共字段
Field[] getFields() -- 获得类的所有公共字段
Field getDeclaredField(String name) -- 获得类声明的命名的字段
Field[] getDeclaredFields() -- 获得类声明的所有字段 

调用方法

获得方法信息的方法

Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法
Method[] getMethods() -- 获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
Method[] getDeclaredMethods() -- 获得类声明的所有方法

当我们从类中获取了一个方法后,我们就可以用 invoke() 方法来调用这个方法。invoke 方法的原型为:

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

利用反射创建数组

数组在Java里是比较特殊的一种类型,它可以赋值给一个Object Reference 其中的Array类为java.lang.reflect.Array类。我们通过Array.newInstance()创建数组对象,它的原型是:

public static Object newInstance(Class<?> componentType, int length)throws NegativeArraySizeException {return newArray(componentType, length);}

而 newArray 方法是一个 native 方法,它在 HotSpot JVM 里的具体实现我们后边再研究,这里先把源码贴出来:

private static native Object newArray(Class<?> componentType, int length)throws NegativeArraySizeException;

注意事项


  • 反射会额外消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射
  • 反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题

Java无所不能的反射在Android中需要熟练的知识相关推荐

  1. android Java开发设计模式及在android中的应用解析

    android Java开发设计模式及在android中的应用解析 什么是设计模式: 可以用一句话概括设计模式---设计模式是一种利用OOP的封闭.继承和多态三大特性,同时在遵循单一职责原则.开闭原则 ...

  2. Java泛型应用之打造Android中ListView和GridView万能适配器【CommonAdapter】--超简洁写法

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/52813227 [DylanAndroid的csdn博客] 在android中使 ...

  3. android androidruntime java,java – Runtime.exec():在Android中重启?

    重新启动在Android中正常工作.你可能没有正确地执行runtime.exec(). 你需要处理 public static void rebootSU() { Runtime runtime = ...

  4. Android中的一些基础知识(二)

    这几天在回顾Android的基础知识,就把一些常见的知识点整理一下,以后忘了也可以翻出来看一看. 简单介绍一下Activity的生命周期  在API文档中对生命周期回调的函数描述的很详细,这里我只是翻 ...

  5. java 手势识别_java – 如何在Android中实现手势识别

    有一天我得到它的工作,失去的一部分是,我必须禁用滑动关闭手势,并添加DismissOverlayView到我的布局,步骤: >禁用滑动关闭手势 将AppTheme样式添加到您的styles.xm ...

  6. java bean的反射类_JAVA中反射机制五(JavaBean的内省与BeanUtils库)

    内省(Introspector) 是Java 语言对JavaBean类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法 ...

  7. java隐藏密钥_java – 在Android中隐藏密钥库密码的最佳方法是什么?

    我是Android开发和实现SSLSockets的新手.在做了一些挖掘后,我能够设置一个正常工作的简单服务器/客户端.我认为实现可以使用一些工作,并且难以将密码加载到密钥库而不用纯文本.这是客户端的一 ...

  8. android java代码重启,如何在Android中重启服务?

    has anyone know how to restarting a service in android?? i have a service that called when device is ...

  9. android java 延时函数,如何在Android中设置文本之间的延迟

    由于不能在UI线程上调用Thread.sleep(只显示最终结果),因此应该在另一个线程上执行此操作,例如: 在构造函数上: private Handler handler; public void ...

最新文章

  1. Nagios插件NDOUtils安装
  2. IJCAI 2020灭霸式拒稿,AI审稿是否更公平?
  3. PowerShell 6.2 PSCommandNotFoundSuggestion
  4. python 显示数据库数据tk_如何使用python显示从Mysql表获取的Tkinter treeview中的数据...
  5. 2020-11-24(Windows保护模式学习笔记(1)—— 段寄存器与段权限检查)
  6. vant 里面找不到轮播图_5分钟搞定,高逼格动态LOGO图
  7. Python学习第一天-第2节
  8. jQuery LigerUI 插件介绍及使用之ligerGrid
  9. 2009年高考作文------拉风篇
  10. .NET应用服务器(中间件)来到
  11. java电商项目简历_一文解析从写简历,到面试、谈薪酬技巧和防坑指南
  12. Python:混合动力汽车能量管理_动态规划简版(1/2)
  13. kindle电子书和新闻推送及RSS资源…
  14. html化妆品商城设计,基于HTML5的彩妆购物网站设计任务书
  15. JavaEE#JCA
  16. gaussDB200 单节点安装
  17. 单片机控制直流电机(风扇)电路详解
  18. 荣耀9i升级鸿蒙,千元小萌脸 荣耀9i实力非凡
  19. c语言如何解超越方程
  20. 跳槽真的难吗?20节专项课揭秘面试潜规则

热门文章

  1. lambda表达式对比
  2. 解决VMWare Workstation 响应慢
  3. 用CSS使DIV水平居中
  4. 打开tomcat的管理平台,管理应用
  5. blog.mm index.php,每天一个WordPress文件:index.php
  6. php导入sql文件到数据库中,PHP执行SQL文件并将SQL文件导入到数据库
  7. python 公司年会抽奖_Python语言学习之用Python写公司年会抽奖程序
  8. 又是一年春,爱花的设计师来收“十二月花语插画”
  9. 国内人气设计师交流平台集设
  10. 设计师吃饭的家伙还问别人要?必要软件、效率工具、插件搜集给你