zoukankan      html  css  js  c++  java
  • 反射

    类的加载器

    类的加载

    当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

    l  加载

    就是指将class文件读入内存,并为之创建一个Class对象。

    任何类被使用时系统都会建立一个Class对象

    l  连接

    验证 是否有正确的内部结构,并和其他类协调一致

    准备 负责为类的静态成员分配内存,并设置默认初始化值

    解析 将类的二进制数据中的符号引用替换为直接引用(变量赋值)

    l  初始化

    就是我们以前讲过的初始化步骤

    反射

    Class

    获取Class的三种方式:

    Person p=new Person();//自定义类

    //1.通过Object类中的getClass方法获取

    Class c1=p.getClass();

    //2.通过类名获取

    Class c2=Person.class;

    //3.通过完整的包名加类名获取

    Class c3=Class.forName("com.oracle.d03.Person");

    Constructor通过反射获取构造方法:

    getConstructors()  //反射获取所有公共构造方法,返回个Constructor[]

    getConstructor(Class<?>... parameterTypes)  //反射获取某个指定参公共构造方法,

    newInstance(参数)  //通过反射获取的构造方法,创建对象,

    例:

    //获取某个公共的构造方法

        Constructor con1=c.getConstructor(String.class,int.class);

        //通过构造方法创建对象

        Object obj=con1.newInstance("000",2);

        System.out.println(obj);

    getDeclaredConstructors()  //获取所有构造方法(包含私有)

    getDeclaredConstructor(Class<?>... parameterTypes)  //获取某个指定参构造方法(包含私有)

    setAccessible(boolean  flag)  //暴力反射,违反了面向对象的封装,所有不使用。

    例:

    //获取某个私有构造方法

    Constructor cons=c.getDeclaredConstructor(String.class);

    //暴力反射

    cons.setAccessible(true);

    Object obj=cons.newInstance("aaa");

    Field通过反射获取成员变量

    getFields() 获取所有公共变量

    getField (String name) 获取某个公共成员变量

     

    getDeclaredFields() 获取所有成员变量

    getDeclaredField(String name) 获取某个成员变量

    set(Object , 值)  方法,给获取的变量赋值

    通过反射获取成员变量并赋值:

    获取指定的成员变量(私有成员变量,通过setAccessible(boolean flag)方法暴力访问)

     

    Field fields=c.getDeclaredField("age"); //获取指定成员变量

    Person p=new Person(); //创建对象

    fields.set(p, 18); //赋值

    System.out.println(p);

    Method通过反射获取成员方法:

    getMethods() 获取所有public 修饰的方法

    getMethods(String  name , Class<?>... parameterTypes)  获取某个成员方法

    newInstance(参数)  通过反射获取的方法,创建对象,

    newInstance()  Class类中方法,快速创建对象,只能调空参方法

    invoke(Object obj , 参数)  调用当前Method代表的方法

    例:

    获取单个成员方法

        Method method=c.getMethod("sleep",String.class);

    Object p = c.newInstance(); //创建对象

        method.invoke(p,"aa"); //调用

    获取私有成员方法,步骤如下:

    1. 获取Class对象

    2. 获取构造方法

    3. 通过构造方法,创建对象

    4. 获取指定的方法

    5. 开启暴力访问

    6. 执行找到的方法

    泛型擦除

    程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为泛型的擦除。我们可以通过反射技术,来完成向有泛型约束的集合中,添加任意类型的元素

     

    ArrayList<Integer> arr=new ArrayList<Integer>();

    //通过ArrayList的字节码文件对象

    Class c=arr.getClass();

    //通过反射获取add方法

    Method add=c.getMethod("add",Object.class);

    add.invoke(arr, "aaa");

    反射配置文件

    读取Peoperties.txt文件中的数据,通过反射技术,来完成Person对象的创建

    //明确配置文件的路径,IO字符输入流

    FileReader fr=new FileReader("src/com/oracle/d02/config.Properties");

    //创建Properties集合

    Properties pro=new Properties();

    //从配置文件中读取键值队到集合中

    pro.load(fr);

    //从集合中获取完整的包名加类名

    String ClassName=pro.getProperty("ClassName");

    //获取方法名

    String MethodName=pro.getProperty("MethodName");

    //通过反射获取字节码文件

    Class c=Class.forName(ClassName);

    //创建对象

    Object obj=c.newInstance();

    //获取方法

    Method method=c.getMethod(MethodName);

    //调用方法

    method.invoke(obj);

  • 相关阅读:
    Parameter Binding in ASP.NET Web API
    Which HTTP methods match up to which CRUD methods?
    ErrorHandling in asp.net web api
    HttpStatusCode
    Autofac Getting Started(默认的构造函数注入)
    Autofac Controlling Scope and Lifetime
    luvit 被忽视的lua 高性能框架(仿nodejs)
    undefined与null的区别
    VsCode中使用Emmet神器快速编写HTML代码
    字符串匹配---KMP算法
  • 原文地址:https://www.cnblogs.com/hhthtt/p/10632640.html
Copyright © 2011-2022 走看看