美文网首页
java 反射基础

java 反射基础

作者: 写代码的向日葵 | 来源:发表于2019-07-25 23:35 被阅读0次

    1.java反射基础

    2.java反射进阶


    反射的两个显著的作用

    • 反编译: .class —> .java
    • 通过反射机制访问java对象中的属性、方法、构造方法等。

    反射机制需要使用到的类

    • java.lang.Class ————类的创建
    • java.lang.reflect.Constructor————反射类中的构造方法
    • java.lang.reflect.Field————反射属性
    • java.lang.reflect.Method————反射方法
    • java.lang.reflect.Modifier————访问修饰符的信息
    实现反射,实际上是得到Class对象,使用java.lang.Class这个类。这是Java反射机制的起源,当一个类被加载后,Java虚拟机会自动产生一个Class对象。
    

    1.三种获取Class对象的方式

    (1).反射机制获取类,以简单获取Reflect类为例

    Class  c1=Class.forName("com.zhangqing.Reflect")
    

    (2).java中每个类都有Class属性

    Class c2=Reflect.Class;
    

    (3).通过getClass方法获取

    Class c3=new Reflect().getClass();
    

    这三种初始化方式的区别在于:

    • 第一种Class.forName方式,会让ClassLoader装载类,并执行类的初始化。
    • 第二种getClass()方式,返回类对象运行时真正所指的对象、所属类型的Class对象。
    • 第三种Reflect.class方式,ClassLoader装入内存,不对类进行类的初始化操作。\color{red}{区分的重点在于是否进行初始化和是否在实例中获取}

    2.无参数创建对象

    (1). forName 中的参数需要填入全路径名

    Class c=Class.forName("com.zhangqing.Reflect");
    Object o=c.newInstance();
    

    New和newInstance()的区别

    • New是直接创建一个实例,同时完成类的装载和连接。
    • newInstance()是使用类的加载机制,创建了一个实例。这个类已经被加
      载,并且已经被连接,这是因为forName会让ClassLoader装载类和进行类的初始化工作,其实际创建的是Object对象.
    • 使用类加载机制可以很灵活地创建类的实例,当更换类的时候,无须修改以前的代码。
    • New是一个关键字,可以传入参数取决于对象的构造方法,而newInstance是一个方法,只能传入无参数构造。

    3.有参数创建对象

    有参构造方法在调用参数时需要药天蝎的参数类型:

    Constructor<?> csr=c.getConstructor(String.class,int.class);
    Object o=csr.newInstance("zhangqing",26);
    

    这里的getConstructor方法会返回一个Constructor对象,它反反映类此Class对象所表示的类指定的公共构造方法。

    4.反射类中的属性需要使用Field对象

        Field field=cls.getDeclaredField("name");
    

    使用setAccessible取消封装,特别是可以取消私有字段的访问限制。

        field.setAccessible(true);
    

    O是属性所在的类对象(类的实例)

        field.set(0,"zhangqing");
    
    • Field类描述的是属性对象,其中可以获取到很多属性的信息,包括名字、属性类型、属性的注解。
    • 在安全管理器中会使用checkPermission方法来检查权限,而setAccessible(true)并不是将方法的权限改为public,而是取消Java的权限控制检查,所以即使是public方法,其accessible属性默认也是false.

    5.修改属性中修饰符

        Field field=cls.getDeclaredField("name");
        String priv=Modifier.toString(file.getModifiers());
    
    • getModifiers()返回的是一个int类型的返回值,代表类、成员变量、方法的修饰符。

    6.反射类中的方法

    (1).获取类中的方法

       Method m=c.getDeclaredMethod("setName",String.class);
    

    (2).通过反射调用方法

        m.invoke(c,"zhangqing");
    
    • getDeclaredMethod()获取的是类自身声明的所有方法,包含public,protected和private方法。
    • Method中的invoke方法用于检查AccessibleObject的override属性是否为true.
    • AccessiobleObject是Method、Field、Constructor的父类,override属性默认为false,可调用setAccessible方法改变,如果设置为true,则表示可以忽略访问权限的限制,直接调用。

    进阶内容见下一篇java反射进阶

    相关文章

      网友评论

          本文标题:java 反射基础

          本文链接:https://www.haomeiwen.com/subject/wnnkrctx.html