Live2D

反射的学习笔记

二、反射

  1. reflection(反射)

    1.1、初识反射:

    package com.lix.reflection;
    
    /**
     *
     * @author lix
     * 什么叫反射
     */
    public class Test extends Object {
        public static void main(String[] args) throws ClassNotFoundException {
            //通过反射获取类的Class对象
            Class<?> c1 = Class.forName("com.lix.reflection.User");
            System.out.println(c1);
    
            Class<?> c2 = Class.forName("com.lix.reflection.User");
            Class<?> c3 = Class.forName("com.lix.reflection.User");
            Class<?> c4 = Class.forName("com.lix.reflection.User");
            /**
             * 一个类在内存中只有一个Class对象
             * 一个类被加载后,类的整个结构都会封装在Class对象中
             */
            System.out.println(c2.hashCode());
            System.out.println(c3.hashCode());
            System.out.println(c4.hashCode());
    
        }
    
    }
    
    /**
     * 实体类
     *
     */
    class User{
         private String name;
         private int id;
         private int age;
    
        public User() {
        }
    
        public User(String name, int id, int age) {
            this.name = name;
            this.id = id;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    
    package com.lix.reflection;
    
    /**
     * @author lix
     */
    public class Test01 {
    
        public static void main(String[] args) throws ClassNotFoundException {
            Person person = new Student();
            System.out.println("这个人是:"+person.name);
    
            //方式一 :通过对象获得
            Class c1 = person.getClass();
            System.out.println(c1.hashCode());
    
            //方式二:forName 获得
            Class<?> c2 = Class.forName("com.lix.reflection.Student");
            System.out.println(c2.hashCode());
    
            //方式三:通过类名.class获得
            Class<Student> c3 = Student.class;
            System.out.println(c3.hashCode());
    
            //方式四: 基本内置类型的包装类都有一个Type属性
            Class<Integer> c4 = Integer.TYPE;
            System.out.println(c4.hashCode());
    
            //获得父类类型
            Class c5 = c1.getSuperclass();
            System.out.println(c5);
    
        }
    }
    class Person{
        public String name;
    
        public Person() {
        }
    
        public Person(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return super.toString();
        }
    }
    class Student extends Person{
        public Student() {
            this.name = "学生";
        }
    }
    class Teacher extends Person{
        public Teacher() {
            this.name = "老师";
        }
    }
    

    1.2、通过反射获取并了解类

    package com.lix.reflection;
    
    import java.lang.annotation.ElementType;
    
    /**
     * @author lix
     * 所有类型的class
     */
    @SuppressWarnings("all")
    public class Test03 {
        public static void main(String[] args) {
            Class<Object> c1 = Object.class; //类
            Class<Comparable> c2 = Comparable.class;//接口
            Class<String[]> c3 = String[].class;//一维数组
            Class<int[][]> c4 = int[][].class;//二维数组
            Class<Override> c5 = Override.class;//注解
            Class<ElementType> c6 = ElementType.class;//枚举
            Class<Integer> c7 = Integer.class;//基本数据类型
            Class<Void> c8 = void.class;//void
            Class<Class> c9 = Class.class; //class
    
            System.out.println(c1);
            System.out.println(c2);
            System.out.println(c3);
            System.out.println(c4);
            System.out.println(c5);
            System.out.println(c6);
            System.out.println(c7);
            System.out.println(c8);
            System.out.println(c9);
            /**
             * 只要元素类型与维度一样,就是一个class
             */
            int[] a = new int[10];
            int[] b = new int[100];
            System.out.println(a.getClass().hashCode());
            System.out.println(b.getClass().hashCode());
    
        }
    }
    
    

    1.3 、从内存分析class

    package com.lix;
    
    /**
     * @author lix
     */
    public class Test04 {
        public static void main(String[] args) {
            A a = new A();
            System.out.println(A.m);
        }
        /**
         * 1.加载到内存,会产生一个类对应的class对象
         * 2.链接, 链接结束后 m = 0
         * 3.初始化
                <clinit></clinit>(){
             System.out.println("A类静态代码块初始化");
            m = 300
            m = 100
         最后得出 m=100
         }
         */
    
    
    }
    
    class A{
        static {
            System.out.println("A类静态代码块初始化");
            m = 300;
        }
    
        static int m = 100;
        public A() {
            System.out.println("A类的无参构造初始化");
        }
    }
    

    1.4、类的初始化

    • 主动引用(一定会发生类的初始化)
    • 被动引用(一定不会发生类的初始化)
    package com.lix.reflection;
    
    /**
     * @author lix
     * 测试类什么时候hi被初始化
     */
    public class Test05 {
        static {
            System.out.println("main类被加载");
        }
    
        public static void main(String[] args) throws ClassNotFoundException {
            //1.主动引用
    //        Son son = new Son();
    //
    //        //反射也会产生主动引用
    //        Class.forName("com.lix.reflection.Son");
    
            //不会产生类的引用的方法
           // System.out.println(Son.b);
    
           // Son[] array = new Son[5];
    
            System.out.println(Son.N);
        }
    
    }
    
    class Father {
        static int b = 2;
        static {
            System.out.println("父类被加载");
        }
    }
    
    class Son extends Father {
        static {
            System.out.println("子类被加载");
            m = 300;
        }
        static int m = 100;
        static final int N =1;
    }
    
    

    1.5、类加载器

    1.5.1、类运行流程图:

    1.5.2、通过反射获得类的运行时信息

    package com.lix.reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * @author lix
     * 获取类的信息
     */
    public class Test06 {
    @SuppressWarnings("all")
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
            Class<?> c1 = Class.forName("com.lix.reflection.User");
    
            //获得类的名字
            System.out.println(c1.getName()); //获得类名+包名
            System.out.println(c1.getSimpleName()); //获得类名
    
            //获得类的属性
             Field[] fields = c1.getFields();//只能找到public属性
        Field[] fields1 = c1.getDeclaredFields();//能找到全部属性
        for (Field field : fields1) {
            System.out.println(field);
        }
        //获得指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name);
    
        //获得类的方法
        System.out.println("==================");
        Method[] m1 = c1.getMethods();//获得父类全部的public方法
        for (Method method : m1) {
            System.out.println(method);
        }
        Method[] m2 = c1.getDeclaredMethods();//获得苯类的所有方法
        for (Method method2 : m2) {
            System.out.println(method2);
        }
        System.out.println("==================================");
        Method getName = c1.getMethod("getName", null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);
    
        //获得指定的构造器
        System.out.println("===================---------===========");
        Constructor<?>[] constructors = c1.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        Constructor<?> constructor1 = c1.getConstructor();
        System.out.println(constructor1);
    
    }
    }
    

    1.5.3、通过反射动态的创建对象

    package com.lix.reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @author lix
     * 通过反射动态的创建对象
     */
    @SuppressWarnings("all")
    public class Test07 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
            Class<?> c1 = Class.forName("com.lix.reflection.User");
    
            //构造一个对象
            User user = (User)c1.newInstance();//本质是调用了无参构造器
            System.out.println(user);
    
            //通过构造器创建对象
            Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
            Object lix = declaredConstructor.newInstance("lix", 001, 20);
            System.out.println(lix);
    
            //通过反射调用普通方法
            User user1 = (User)c1.newInstance();
            //通过反射获取一个方法
            Method setName = c1.getDeclaredMethod("setName", String.class);
            setName.invoke(user1,"lix");
            System.out.println(user1.getName());
    
            //通过反射操作属性
            User user2 = (User)c1.newInstance();
            Field name = c1.getDeclaredField("name");
            //不能直接操作私有属性,需要关闭程序的安全检测,setAccessible
            name.setAccessible(true);
            name.set(user2,"ll");
            System.out.println(user2.getName());
    
    
        }
    }
    
    
posted @ 2020-10-22 17:43  六爻呈乾  阅读(83)  评论(0编辑  收藏  举报