• 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);
        }
    反射越过泛型检查
  • 相关阅读:
    ios8的图标尺寸
    Xcode 6.1 正式版如何创建一个Empty Application
    xcode真机调试
    iOS基础控件
    iOS开发系列之二 – UILabel 用法小结
    (转)25个增强iOS应用程序性能的提示和技巧--初级篇
    IOS开发第三方开源库
    ios -- NSdata 与 NSString,Byte数组,UIImage 的相互转换
    4.组件的语法糖注册方式
    3.父组件和子组件
  • 原文地址:https://www.cnblogs.com/feng0001/p/10992410.html
Copyright © 2020-2023  润新知