反射

来源:互联网 发布:sql在哪停止 编辑:程序博客网 时间:2024/05/22 01:42
1.类加载器
 根类加载器:Bootstrap ClassLoder
  负责JAVA核心类的加载,如String,System等,在IDK中JRE的lib文件下的rt.har文件
 扩展器加载器:Extension ClassLoder
  JRE中的ext目录
 系统类加载器:System ClassLoder
  JVM启动时加载来自JAVA命令的class文件。
2.反射
  通过一个class文件对象,去使用该文件中的成员变量,构造方法,成员方法。
 获取class文件对象(代表字节码文件对象):
 class类:
  成员变量  Filed
  构造方法 Constructor
  成员方法 Method
 获取class文件对象的方式:
  A:Object类的getClass方法

   Person p = new Person();
   Class c = p.getClass();

  B:数据类型的静态属性
   
   Class c = Person.class;

  C:Class类中的静态方法

   Class c = Class.forName(“全路径的包名”);

一般自己用的时候就用第二种,开发用的第三种,因为第三种是一个字符串,而不是一个具体的类名,我们可以将这样的字符串配置到配置文件中。

例子一: ArrayList<Integer> array 添加一个String数据

   ArrayList<Integer> array = new ArrayList<>();
 //其实ArrayList<Integer>在运行时的对象是Object,Integer是给编译器看的,拿到字节码文件对象,我们可以通过反射,调用add方法来给集合添加String数据。
        Class c = array.getClass();
        Method m = c.getMethod("add",Object.class);
        m.invoke(array,"yanxi");
        System.out.println(array);

例子二: 写一个方法 public void setProperty(Object obj,String properName,Object          value) 将obj对象的properName成员内容设置成value。

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

测试:
public class ToolDemo {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Person p = new Person();
        Tool  t = new Tool();
        t.setProperty(p,"name","yanxi");
        t.setProperty(p,"age",17);
        System.out.println(p);
    }
}
class Person{
    private  String name;
    public int age;

    @Override
    public String toString() {
        return name  +  "--"  + age ;
    }
}
结果:yanxi--17

3.动态代理
 在程序运行过程中产生的对象。

4.设计模式
模板设计模式:定义一个算法的骨架(抽象类),将具体实现延迟在子类中实现。
装饰模式:使用被装饰子类的一个实例,是继承的替代方案。(抽象类)


0 0
原创粉丝点击