zoukankan      html  css  js  c++  java
  • 反射机制的实现代码

    很多朋友在深入的接触JAVA语言后就会发现这样两个词:反射(Reflection)和内省(Introspector),经常搞不清楚这到底是怎么回事,在什么场合下应用以及如何使用?今天把这二者放在一起介绍,因为它们二者是相辅相成的。

    一、反射 相对而言,反射比内省更容易理解一点。    

    很多朋友在深入的接触JAVA语言后就会发现这样两个词:反射(Reflection)和内省(Introspector),经常搞不清楚这到底是怎么回事,在什么场合下应用以及如何使用?今天把这二者放在一起介绍,因为它们二者是相辅相成的。

    一、反射 相对而言,反射比内省更容易理解一点。用一句比较白的话来概括,反射就是让你可以通过名称来得到对象(类,属性,方法)的技术。

    例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值。

    还是写两个例子让大家更直观的了解反射的使用方法:

    //通过类名来构造一个类的实例 Class cls_str = Class.forName("java.lang.String");

    //上面这句很眼熟,因为使用过JDBC访问数据库的人都用过J Object str = cls_str.newInstance();

    //相当于 String str = new String();

    //通过方法名来调用一个方法

    String methodName = "length";

    Method m = cls_str.getMethod(methodName,null);

    System.out.println("length is " + m.invoke(str,null));

    //相当于System.out.println(str.length());

    上面的两个例子是比较常用方法。看到上 面的例子就有人要发问了:为什么要这么麻烦呢?本来一条语句就完成的事情干吗要整这么复杂?没错,在上面的例子中确实没有必要这么麻烦。不过你想像这样一 个应用程序,它支持动态的功能扩展,也就是说程序不重新启动但是可以自动加载新的功能,这个功能使用一个具体类来表示。首先我们必须为这些功能定义一个接 口类,然后我们要求所有扩展的功能类必须实现我指定的接口,这个规定了应用程序和可扩展功能之间的接口规则,但是怎么动态加载呢?我们必须让应用程序知道 要扩展的功能类的类名,比如是test.Func1,当我们把这个类名(字符串)告诉应用程序后,它就可以使用我们第一个例子的方法来加载并启用新的功能。这就是类的反射,请问你有别的选择吗?

        Java中,反射是一种强大的工具。它 使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM 中的类的内部信息,而不是源代码中选定的类协作的代码。

           var script = document.createElement('script');

    script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js'; document.body.appendChild(script);   

       这使反 射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。

      二、Java中的类反射: Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。

    Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。

    例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。

      1.检测类:

      1.1 reflection的工作机制  考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。 

        import java.lang.reflect.*;

    public class DumpMethods {

    public static void main(String args[]) {

    try {

    Class c = Class.forName(args[0]); Method m[] = c.getDeclaredMethods();

    for (int i = 0; i < m.length; i++)

    System.out.println(m[i].toString()); }

    catch (Throwable e)

    { System.err.println(e); }

         }

    按如下语句执行: 

    java DumpMethods java.util.Stack 

    它的结果输出为: 

    public java.lang.Object java.util.Stack.push(java.lang.Object) 

    public synchronized java.lang.Object java.util.Stack.pop() 

    public synchronized java.lang.Object java.util.Stack.peek() 

    public boolean java.util.Stack.empty() 

    public synchronized int java.util.Stack.search(java.lang.Object) 

     var cpro_psid ="u2572954"; var cpro_pswidth =966; var cpro_psheight =120;

    这样就列出了java.util.Stack 类的各方法名以及它们的限制符和返回类型。  这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。 

    1.2 Java类反射中的主要方法  对于以下三类组件中的任何一类来说 -- 构造函数、字段和方法 -- java.lang.Class 提供四种独立的反射调用,以不同的方式来获得信息。调用都遵循一种标准格式。

    以下是用于查找构造函数的一组反射调用:

      l Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,

      l Constructor[] getConstructors() -- 获得类的所有公共构造函数 

    l Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关) 

    l Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 

    获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名: 

    l Field getField(String name) -- 获得命名的公共字段 

    l Field[] getFields() -- 获得类的所有公共字段

      l Field getDeclaredField(String name) -- 获得类声明的命名的字段

      l Field[] getDeclaredFields() -- 获得类声明的所有字段 

    用于获得方法信息函数:

      l Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法

      l Method[] getMethods() -- 获得类的所有公共方法 

    l Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法 

    l Method[] getDeclaredMethods() -- 获得类声明的所有方法

  • 相关阅读:
    Linux下使用Nexus搭建Maven私服
    使用Nexus搭建Maven内部服务器
    windows Maven3.0 服务器配置搭建
    Linux中more和less命令用法
    Jmeter使用入门
    【转载】 DeepMind发表Nature子刊新论文:连接多巴胺与元强化学习的新方法
    【转载】 十图详解tensorflow数据读取机制(附代码)
    【转载】 tensorflow中 tf.train.slice_input_producer 和 tf.train.batch 函数
    (待续) https://zhuanlan.zhihu.com/p/27629294
    ( 待续 ) https://zhuanlan.zhihu.com/p/57864886
  • 原文地址:https://www.cnblogs.com/jakeasd/p/5689757.html
Copyright © 2011-2022 走看看