zoukankan      html  css  js  c++  java
  • Java反射机制

    Java反射机制使程序运行时能动态加载类对象, 并能够获得该类的字段和方法. 对于一些通过多态和动态绑定的程序, 我们可以通过读取配置文件, 再利用Java反射实现的方式来替换. 但是反射会带来如资源消耗, 破坏封装性和安全问题.

    常见应用

    • 反射机制常用于框架开发
    • Eclipse等IDE获取类的方法
    • 动态代理
    • 跳过泛型检查

    主要操作

    1. 获取class, 有三种方式:
    1
    2
    3
    4
    5
    Person p = new Person("cdj", 23);
    Class clazz1 = p.getClass();

    Class clazz2 = Person.class;
    Class clazz = Class.forName("me.forz.javaReflect.path.Person");
    1. 获取Constructor
    1
    2
    3
    4

    Constructor c1 = clazz.getConstructor(); // 无参构造器
    Constructor c2 = clazz.getConstructor(String.class, int.class); // 有参
    Person p = (Person) c2.newInstance("constru", 23);
    1. 获取Field
    1
    2
    3
    4
    5
    // 分两种, 是否是private
    // Field f = clazz.getField(fieldName);
    Field f = clazz.getDeclaredField(fieldName);// Field名称
    f.setAccessible(true); //私有字段需要设置此项
    f.set(obj, val);
    1. 获取Method

      同Field, Method也分成是否是private两种, 此处不再赘述. 下面展示一种利用反射跳过泛型检查的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ArrayList<Integer> al = new ArrayList<Integer>();
    al.add(1);
    al.add(2);
    System.out.println(al); //[1, 2]

    Class clazz = Class.forName("java.util.ArrayList");
    Method m = clazz.getDeclaredMethod("add"大专栏  Java反射机制an>, Object.class);
    m.invoke(al, "a");
    System.out.println(al); // [1, 2, a]

    使用

    动态代理

    只能针对接口做代理; 需要实现InvocationHandler接口

    假设有一个Fruit接口, 包含一个eat()方法, FruitImpl是一个实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class  {
    public static void main(String[] args) {
    FruitImpl fi = new FruitImpl();
    fi.eat();// 输出: eating

    MyInvocationHandler mih = new MyInvocationHandler(fi);
    Fruit f = (Fruit) Proxy.newProxyInstance(fi.getClass().getClassLoader(), fi.getClass().getInterfaces(), mih);
    f.eat(); // 输出 beforn eatingn after
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object obj) {
    this.target = obj;
    }


    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("befor");
    method.invoke(target, args);
    System.out.println("after");
    return null;
    }
    }
  • 相关阅读:
    Android自注-15-Activity生命周期
    【v2.x OGE课程 15】 布局相关
    多线程——继承Thread类别
    Kivy A to Z -- Kivy 示例演示自带名单
    Android Training
    [TypeScript] Configuring a New TypeScript Project
    [TypeScript] Installing TypeScript and Running the TypeScript Compiler (tsc)
    [Redux] Fetching Data on Route Change
    [Redux] Wrapping dispatch() to Log Actions
    [Redux] Normalizing the State Shape
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12371074.html
Copyright © 2011-2022 走看看