Java回炉之反射(一)

来源:互联网 发布:windows界面中新建 编辑:程序博客网 时间:2024/05/08 04:37

Java回炉之反射(一)

  • Java回炉之反射一
    • 类的加载
    • 类加载器
    • 获取class文件
    • 获取并使用构造方法
    • 获取并使用成员变量
    • 获取并使用方法
    • 通过反射躲避泛型检查
    • 通用为某个对象的某个字段设置值工具类
    • 动态代理

类的加载

  1. 加载类的时机
    • 创建实例
    • 访问静态变量,或为静态变量赋值
    • 调用静态方法
    • 使用反射强制创建类或对应的Class对象
    • 初始化其子类
    • 使用java.exe运行的主类
  2. 将class文件读入内存,并为之创建一个Class对象。
  3. 验证内部结构
  4. 为静态成员分配内存,设置默认初始化值
  5. 将符号引用替换为直接引用

类加载器

  • Bootstrap 引导类
  • Extension 扩展类
  • System 系统类

获取class文件

  • new Demo().getClass()
  • Demo.class
  • Class.forName(“package.name.Demo”);

获取并使用构造方法

Class c=Class.forName("package.name.Demo");c.getContructors();//获取公共构造方法c.getDeclaredConstructors();//获取所有构造方法Constructor con=c.getConstructor();//参数为对应构造方法的参数对应的Class对象Constructor con=c.getConstructor(int.class);//获取带int参数的构造方法Object obj =con.newInstance();//创建Demo实例Object obj= com.newInstance(2);con.setAccessible(boolean);//参数为true时可以访问private成员

获取并使用成员变量

Class c=Class.forName("package.name.Demo");c.getFields();//获取公共成员变量c.getDeclaredFields();//获取所有成员变量Field f=c.getField(”“);//根据变量名获取字段f.setAccessible(true);//设置强制访问Field f=c.getDeclaredField(”“);//根据变量名获取private字段f.set(new Demo(),"");//给demo的f字段设置值为""

获取并使用方法

Class c=Class.forName("package.name.Demo");c.getMethods();//获取自己及父的类公共方法c.getDeclaredMethods();//获取自己的所有方法Method m=c.getMethod(String name,...);//第一个参数为要获取方法的方法名,后面的参数为要获取方法的参数类型列表m.invoke(new Demo());//调用demo对象的m方法,第二个及其后参数将传递给m方法,返回值为m方法的返回值

通过反射躲避泛型检查

// 创建集合对象ArrayList<Integer> array = new ArrayList<Integer>();// array.add("hello");// array.add(10);Class c = array.getClass(); // 集合ArrayList的class文件对象Method m = c.getMethod("add", Object.class);m.invoke(array, "hello"); // 调用array的add方法,传入的值是hellom.invoke(array, "world");m.invoke(array, "java");System.out.println(array);

通用为某个对象的某个字段设置值工具类

public class Tool {    public void setProperty(Object obj, String propertyName, Object value)            throws NoSuchFieldException, SecurityException,            IllegalArgumentException, IllegalAccessException {        // 根据对象获取字节码文件对象        Class c = obj.getClass();        // 获取该对象的propertyName成员变量        Field field = c.getDeclaredField(propertyName);        // 取消访问检查        field.setAccessible(true);        // 给对象的成员变量赋值为指定的值        field.set(obj, value);    }}

动态代理

本节移植Java回炉之反射(二)动态代理
查看完整源代码

0 0
原创粉丝点击