zoukankan      html  css  js  c++  java
  • 反射

    Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)检查类,接口,变量以及方法的信息。反射还可以让我们在运行期实例化对象,调用方法,通过调用get/set方法获取变量的值。

    通过反射API可以获取程序在运行时刻的内部结构,知道了Java类的内部 结构之后,就可以与它进行交互,包括创建新的对象和调用对象中的方法等。这种交互方式与直接在源代码中使用的效果是相同的,但是又额外提供了运行时刻的灵活性

    反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中的方法拦截功能

    使用反射的一个最大的弊端是性能比较差。相同的操作,用反射API所需的时间大概比直接的使用要慢一两个数量级。不过现在的JVM实现中,反射操作的性能已经有了很大的提升。在灵活性与性能之间,总是需要进行权衡的。应用可以在适当的时机来使用反射API。

    一、动态获取类的信息

    1.1 获取类的Class对象

    所有类型,包括基本类型、数组,都有与之关联的Class类的对象。

    1)编译期已知类的名字,通过.class获取

    Class myObjectClass = MyObject.class;

    2)编译期未知类的名字,但可在运行期获得类名的字符串,通过字符串获取

    Class clazz = Class.forName(className);

    在使用Class.forName()方法时,你必须提供一个类的全名,这个全名包括类所在的包的名字。

    如果在调用Class.forName()方法时,没有在编译路径下(classpath)找到对应的类,那么将会抛出ClassNotFoundException。

    1.2 获取类名

    全限定类名:

    String className = clazz.getName();

    类的名字:

    String simpleClassName = clazz.getSimpleName();

    1.3 获取修饰符

    int modifiers = clazz.getModifiers(); //类只有public和包访问权限

    每个修饰符都是一个位标识。0表示包访问,1表示public, 2表示private,4表示protected

    可使用Modifier类的静态方法来判断是否是期望的访问权限。

    image

    1.4 包信息

    Package packg = clazz.getPackage();

    1.5 父类

    Class superclass = clazz.getSuperclass();

    1.6 实现的接口集合

    Class[] interfaces = clazz.getInterfaces();

    注意:getInterfaces()方法仅仅只返回当前类所实现的接口。当前类的父类如果实现了接口,这些接口是不会在返回的Class集合中的,尽管实际上当前类其实已经实现了父类接口。

    1.7 构造器

    Constructor[] constructors = clazz.getConstructors();

    1.8 方法

    Method[] method = clazz.getMethods();

    1.9 变量

    Field[] method = clazz.getFields();//所有public的变量

    1.10 注解

    Annotation[] annotations = clazz.getAnnotations();

    二、构造器

    2.1 除了可以通过Class对象获取构造器列表,还可以根据入参类型获取指定的构造器。

    Constructor constructor = clazz.getConstructor(new Class[]{String.class});

    2.2 获取指定构造器的入参类型

    Class[] parameterTypes = constructor.getParameterTypes();

    2.3 通过指定构造器实例化一个类

    MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");

    三、成员变量

    3.1 获取指定名称的成员变量
    Field field = clazz.getField("someField");
    String fieldName = field.getName();//变量名
    Object fieldType = field.getType();//变量类型

    3.2 get/set变量值

    MyObject objectInstance = new MyObject();//objetInstance应该是拥有指定变量的类的实例。

    Object value = field.get(objectInstance);

    field.set(objetInstance, value);

    如果变量是静态变量的话(public static),可以传入null做为参数而不用传递拥有该变量的类的实例。

    四、成员方法

    4.1 根据方法名和入参类型获取指定方法

    Method method = clazz.getMethod("doSomething", new Class[]{String.class});//入参为一个String

    Method method = clazz.getMethod("doSomething", null);//空参

    Class[] parameterTypes = method.getParameterTypes();//入参列表

    Class returnType = method.getReturnType();//返回参数

    4.2 调用方法

    Object returnValue = method.invoke(null, "parameter-value1");//这里的null是调用方法的对象,静态方法可直接传null,第二个参数是一个可变参数列表

    五、私有变量和方法

    要想获取私有变量你可以调用Class.getDeclaredField(String name)方法或者Class.getDeclaredFields()方法。同理,构造方法、成员方法等也是。

    image

    image

    image

    image

    image

    六、注解

    6.1 注解的简单介绍

    如果说反射使得很多技术实现(动态代理、依赖注入等)有了基础,那么注解就是使这些技术实现变得平民化的基础。

    Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
    注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。

    要实现一个自定义注解,必须通过@interface关键字来定义。且在@interface之前,需要通过元注解来描述该注解的使用范围(@Target)、生命周期(@Retention)及其他。

    声明一个方法即为注解类型定义了一个元素,方法的声明不允许有参数或throw语句,返回值类型被限定为原始数据类型、字符串String、Class、枚举enums、注解类型,或前面这些的数组,方法可以有默认值。

     

    image

    参考资料

    http://www.infoq.com/cn/articles/cf-java-reflection-dynamic-proxy

    http://ifeve.com/java-reflection-tutorial/

    http://blog.csdn.net/u010150082/article/details/10519261

  • 相关阅读:
    centos python sh recode command not find的解决办法
    Webmail邮件攻防实战技术总结[转]
    关于c#字符串三种逆转方法及性能比较的另外看法
    随机生成10个含有1万个qq邮箱的文件(Python)
    C#对IE使用Proxy(代理)
    sohu邮箱的联系人获取
    Python 的二进制文件读写需要注意的地方
    hotmail解码遇到的&#解码问题
    利用cookie收取Hotmail信件
    CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\web\4b49f661\23a749fc\App_Web_default.aspx.cdcab7d2.zii77dc.dll
  • 原文地址:https://www.cnblogs.com/lddbupt/p/5735340.html
Copyright © 2011-2022 走看看