day27 Java学习 反射

反射(类的加载和加载时机)

 

      类的加载概述:

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

       加载:

                * 就是指将class文件读入内存,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象。

       连接:

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

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

                * 解析:将类的二进制数据中的符号引用替换为直接引用。

       初始化

 

     加载时机:

                 * 创建类的实例。

                *  访问类的静态变量或者为静态变量赋值。

                *  调用类的静态方法。

                *  使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

                *  初始化某个类的子类

                *  直接使用某个Java.exe命令来运行某个主类。

 

 

反射(类加载器的概述和分类)

     类加载器的概述:

                *  负责将 . class文件加载到内存中,并为之生成对应的Class对象。           

 

反射(反射概述)

    反射概述:

                * Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

                * 对于任意一个对象,都能够调用它的任意一个方法和属性。

                * 这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。 

    三种方式:

                * Object了哦的getClass( )方法,判断两个对象是否时同一个字节码文件。

                * 静态属性class,锁对象。

                * Class类中静态方法forName(),读取配置文件

 

反射(通过反射获取带参构造方法并使用)

   Constructor:

                * Class类的newInstance()方法时使用该类无参的构造函数创建对象,如果一个类没有无参的构造函数,就不能这样创建了。可以调用  Class类的getConstructor(String.class, int.class)方法获取一个指定的构造函数然后在调用Constructor类的newInstance()方法创建对象。

             

    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("com.bean.Person");
        Person p1 = (Person) clazz.newInstance(); // 通过无参构造创建对象
        p1.setName("lisi"); // 设置姓名
        p1.setAge(17); // 设置年龄
        System.out.println(p1);
        Constructor c = clazz.getConstructor(String.class, int.class); // 获取有参构造
        Person person = (Person) c.newInstance("张三", 15); // 通过有参构造创建对象
        System.out.println(person.getName() + person.getAge());
    }
反射获取带参(无参)构造方法

 

反射(通过反射获取成员变量并使用)

   Field:

                * Class.getField(String)方法可以获取类中的指定字段(可见的)。如果时私有的可以用getDeclaredField("name")方法获取,通过set( obj,value)方法可以设置指定对象该字段的值。如果是私有的需要先调用setAccessible(true)设置权限访问。

    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("com.bean.Person");
        Constructor c = clazz.getConstructor(String.class, int.class); // 获取有参构造
        Person person = (Person) c.newInstance("张三", 15); // 通过有参构造创建对象
        // Field ff=clazz.getField("name"); //获取姓名字段(字段必须不是private)
        // ff.set(person, "李四"); //修改姓名的值
        Field f = clazz.getDeclaredField("name"); // 暴力反射获取字段
        f.setAccessible(true); // 去除私有权限
        f.set(person, "王五");
        System.out.println(person);
    }
反射获取成员变量
    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("com.bean.Person");
        Constructor c = clazz.getConstructor(String.class, int.class); // 获取有参构造
        Person c1=new Person();      //对象
        Method m=clazz.getMethod("eat");               //获取无参的方法
        m.invoke(c1);
        Method m1=clazz.getMethod("eat",int.class);    //获取有参的方法
        m1.invoke(c1,10);
    }
反射获取方法并使用
    public static void main(String[] args) throws Exception {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(111);
        list.add(222);
        Class clazz = Class.forName("java.util.ArrayList");   //获取字节码对象
        Method m = clazz.getMethod("add", Object.class);      //获取add方法
        m.invoke(list, "abc");
        System.out.println(list);
    }
反射越过泛型检查

 

posted @ 2019-06-09 01:40  锋XX  阅读(149)  评论(0编辑  收藏  举报