zoukankan      html  css  js  c++  java
  • java中的反射

    1.什么是反射

    简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字, 
    那么就可以通过反射机制来获得类的所有信息。 

    简单的来说就是两点,在运行期间:

    1、对于任意一个类,都能够知道这个类的所有属性和方法

    2、对于任意一个类,都能够调用它的任意一个属性和方法

    2.反射的作用。

    为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念, 
        静态编译:在编译时确定类型,绑定对象. 
        动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。 
        一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中,它的灵活性就表现的十分明显。

        其实我们学过的jdbc加载驱动,Class.forName("com.mysql.jdbc.Driver.class").newInstance();这就是反射,现在很多开框架都用到反射机制,hibernate、struts都是用反射机制实现的。 


        它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。 

    3.反射的应用

    下面具体看例子,从反射中我们能得到什么东西。

    (1):Class和ClassLoader

     Class c=Class.forName("className");注明:className必须为类的全路径名,也就是得包含包名,比如:com.test.Test;
     c.getClass();//获取java.lang.Class的Class对象
     c.getClassLoader(); // 获取类的加载器
     c.getSuperclass(); // 获取父类Class对象
     c.getInterfaces() :// 获取类的接口列表,注意返回的是一个数组
     Object obj=c.newInstance();//创建对象的实例 

    (2):Package

    Package p = c.getPackage();
    p.getName());// 获取包名
    p.getImplementationTitle());//获取包标题
    p.getImplementationVendor());//获取提供该实现的组织、供应商或公司的名称
    p.getImplementationVersion());/ 获取该实现的版本
    p.isSealed());// 获取包是否密封的

    (3):Constructor

    Class<?> c = Class.forName("com.test.Test");
    Constructor<?>[] constructors = c.getConstructors();// 获取所有的构造函数
    Constructor<?> constructor = c.getConstructor(String.class);// 获取指定参数列表的构造函数
    constructor.getName()); // 获取构造函数名,没什么意义,肯定是和类同名
    constructor.getModifiers()); // 获取以整数形式返回的此Constructor对象的Java语言修饰符,如public、static、final等
    constructor.isAccessible()); // 获取该Constructor的访问权限
    constructor.getParameterTypes()[0]); // 获取Constructor的参数类型,是个数组
    constructor.isVarArgs()); // 获取此Constructor中是否带了可变数量的参数,即例如"String... str"类型的参数
    TestRef r = (TestRef)constructor.newInstance("123"); // 根据指定的构造方法实例化出一个类的实例来,重要

    (4):Method

    Class<?> c = Class.forName("com.test.Test");
    Method[] ms0 = c.getMethods();// 获取此类包括其父类中所有的public方法
    Method md0 = c.getMethod("publicMethod", int.class, double.class, List.class);// 根据方法名和参数列表获取指定的public方法
    Method[] ms1 = c.getDeclaredMethods();// 返回此类中所有的方法(无访问权限限制),但不包括继承的方法
    Method md1 = c.getDeclaredMethod("privateMethod", new Class[0]);// 根据方法名和参数列表获取指定的任意访问权限的方法,但不包括继承的方法
    md0.getName()); // 获取方法的名字
    md0.isAccessible()); // 获取方法的访问属性
    md0.isVarArgs()); // 获取方法是否带有可变数量的参数
    md0.getReturnType()); // 获取方法的返回类型
    md0.getParameterTypes()[0]//获取方法的参数类型,数组形式,注意一下和下面的方法的区别
    md0.getGenericParameterTypes()[2]);//获取方法的参数化(带泛型)类型,数组形式
    md0.invoke(r, 1, 2.2, new ArrayList<String>())// 反射调用方法,重要

    (5):Field

    Class<?> c = Class.forName("com.test.Test");
    Field[] fs0=getFields();// 获取类中所有public字段,顺序即public的Field定义的顺序
    Field f0 = c.getField("b"); )//根据变量名得到相应的public变量
    Field[] fs1 = c.getDeclaredFields();// 获取类中任意访问权限的字段,顺序即所有Field定义的顺序
    Field f1 = c.getDeclaredField("d");// 根据name获取类中一个任意访问权限的字段
    f0.getName()); // 获取字段名
    f0.getType()); // 获取类的类型
    f0.getBoolean(r)); // 获取某个实例对象该Field的值,什么类型的Field就是getXXX(Object obj)
    f0.getModifiers()); // 以整数形式返回此Field对象的Java语言修饰符,如public、static、final等
    f0.isAccessible()); // 返回Field的访问权限,对private的Field赋值,必须要将accessible设置为true,如下

    4.Modifier枚举值列表

    Field、Constructor、Method中都有getModifiers()方法,返回的是表示此对象的Java语言修饰符,详细看下每个修饰符对应的枚举值:

     

    也就是说如果一个方法是"public static final synchronized"的,那么这个方法的getModifiers()返回的应该是1 + 8 + 16 + 32 = 57,

    转载地址:

    http://www.cnblogs.com/xrq730/p/4862111.html

    http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html

  • 相关阅读:
    Orcale三层嵌套实现分页功能
    在VM虚拟机上安装Microsoft Dynamics CRM 2016 步骤图解及安装注意事项
    CSS 选择器 关系
    C#获取当前程序运行路径的方法集合//获取当前进程的完整路径
    连接QuickBooks Online实现于IOS App数据同步功能的个人记录
    Posix定义的进程线程同步系统调用
    SQL SERVER 数据库事物日志 备份 收缩 腾出空间
    JAVABEAN递归转MAP实现
    第一次迭代——视频点播系统
    cstddef定义了NULL
  • 原文地址:https://www.cnblogs.com/haitaofeiyang/p/7710910.html
Copyright © 2011-2022 走看看