• Java基础-反射机制


    什么是反射?
    在程序运行期间,可以动态加载类,可以动态获取类的信息【属性、方法】,可以动态的调用对象的方法
    java.lang.reflect.*;

    所有的类型或类可以有java.lang.class类来管理

    类通过对象来管理

    Class 类 类型,其对象用来管理指定类或类型的相关信息

    例如:要管理java.lang.String 类,则需要获取Class类的对象

    获取类 类型

    获取Class类 类型的对象(Class类的对象)有3种方式

    1 动态加载类 Class obj = static forName(包名.类名);

    Class<?> obj=Class.forName(className);

    2 通过Object对象的getClass()方法

    例1 “abc”.getClass();

    例2 Person p1 = new Person();  Class c1=p1.getClass();

    3 通过数据类型(基础+引用)的静态属性 .class

    例 int.class

    Class类的方法

    String getName(); 获取类名(含包名)

    String getSimpleName(); 获取类名

    例子 Class aa;  aa.getName();

    例子2-动态加载类

    String className=args[0];//完整的包名.类名 如java.lang.String

    Class<?> obj(obj是一个类)=Class.forName(className);

    //Object o(o才是对象)=obj.newInstance();

    String show = odj.getName;

    println(show);

    or

    if(o instanceOf Integer){...}

    =================

    Class c

    c是Class类的对象

    c也是一种具体的类

    Class<?> obj(obj是一个类)=Class.forName(className);

    Object o(o才是对象)=obj.newInstance();

    //obj.newInstance()调用默认构造器

    Office oc=(Office)o;//Office是一个接口,o可以取值word、excel等实现了Office接口的类

    //Office和Object有一个共同的儿子word或女儿excel或...

    oc.start();

    //反射和多态结合,业务更加灵活..

    //即动态加载类、动态创建该类的对象..

    示例代码:

    public class ReflectionTest {
    
        public static void main(String[] args) {
            //通过args接收参数
            try {
                String className = args[0];//必须是完整路径java.*...
                Class<?> class1=Class.forName(className);
                Object object=class1.newInstance();
                Office office=(Office) object;
                office.start();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    
    }

    =================

    常用的反射:
    类类型
    构造器类型
    属性
    方法
    ====

    获取给定类中的所有构造器:
    1加载类,并获取Class类的对象(目标:管理指定的类)
    Person.class;
    new Person.getClass();
    Class.forName("Person");
    2调用Class类提供的getConstructors()来获取所有的public权限的构造
    器,获取的所有构造器会组成一个数组,由
    java.lang.reflect.Constructor来管理
    tem.getDeclaredConstuctors()--反射所有
    3遍历
    3-1 获取构造器的名称 tem.getName()
    3-2 获取构造器的参数 tem.getParametertTypes()
    3-3 获取形式参数 t.getSimpleName()

    获取属性:
    1、同上
    2、java.lang.reflect.Field//字段反射类
    调用Class类提供的getFields()--【只看public】方法,获取所有属性并
    组成一个数组,【但getDeclaredFields()-反射所有权限的属性】
    3、遍历,显示 【class】getType()属性的类型 getName()属性的名称-+

    获取方法:
    1、同上
    2、java.lang.reflect.Method
    getMethods()--含父类、public
    getDeclaredMethods()--不含父类、可以private
    3、遍历
    [String]getName();
    [Class[]]getParameterTypes()
    getSimpleName

    可变参数:
    public int add(int ... a);
    public int add(int[] b);

    ==========================

    反射的应用:

    构造器、方法、属性、数组的反射

    1、构造器的反射

    先搞一个对象

    import java.util.Date;
    
    public class Person {
        // 属性
        private String name;
        private Date birthday;
    
        // 构造器
        public Person() {
        }
    
        private Person(String name) {
            super();
            this.name = name;
        }
    
        public Person(String name, Date birthday) {
            super();
            this.name = name;
            this.birthday = birthday;
        }
    
        // 访问器、设定器
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        // 功能方法
        public int add(int a, int b) {
            return 9527 + a + b;
        }
    
        public void show() {
            System.out.println("show方法被执行");
        }
    
        private void show(String s) {
            System.out.println("show-s方法被执行");
        }
    
        public double area(double d1, double d2) {
            return d1 + d2;
        }
    
        @Override
        public String toString() {
            return "姓名:" + name + "	生日" + birthday;
        }
    }

    再看看简单的应用:

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class ReflectUSED {
    
        public static void main(String[] args) {
            // 1 默认构造器的反射
            // 要求被反射的对象有正宗的默认构造器 通过newInstance()来实现
            try {
                Class class1 = Class.forName("jee.反射.反射的应用.Person");
                Object object = class1.newInstance();
                System.out.println(object.toString());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            // 2 带参数的构造器
            // 先【Class】getConstuctor(Class..paramTypes)来获取Constructor对象
            // 后【Constructor】newInstance(Object..paramTypes)来创建对象
            try {
                // 加载类
                Class class1 = Class.forName("jee.反射.反射的应用.Person");
                // 获取带一个String类型的构造器
                Constructor cst1 = class1.getDeclaredConstructor(new Class[] { String.class });
                // Constructor cst2 = class1.getConstructor(new Class[]
                // {String.class });
                // (可选)放开权限,当构造器是private是也可以通过反射使用
                cst1.setAccessible(true);// 否则报异常:权限不对
                // 创建对象
                Object object = cst1.newInstance(new Object[] { "刘德华" });
                // 关闭权限(可选)
                cst1.setAccessible(false);
                // 显示
                System.out.println(object);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            // 3 方法的反射,注意权限问题
            try {
                Class class1 = Class.forName("jee.反射.反射的应用.Person");
                Object object = class1.newInstance();
                // 无参
                Method method = class1.getMethod("show", new Class[] {});
                // 有参
                Method method2 = class1.getDeclaredMethod("show", new Class[] { String.class });
                // 可变参数
                // Method method3 = class1.getMethod("show()", new Class[] {int[].class });
                method.invoke(object, new Object[] {});
                method2.setAccessible(true);
                method2.invoke(object, new Object[] { "show的实参" });
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
    
            // ==============
    
        }
    
    }

    ///////////////////////////////练习题

    /**
     * 2016年5月24日下午12:42:41
     */
    
    package d518Reflect;
    
    import java.lang.reflect.Array;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
     interface Office {
        void start();
    }
    
    class Word implements Office {
        @Override
        public void start() {
            System.out.println("Word start");
        }
    }
    
    class Excel implements Office {
        @Override
        public void start() {
            System.out.println("Excel start");
        }
    }
    
    class PowerPoint implements Office {
        @Override
        public void start() {
            System.out.println("PowerPoint start");
        }
    }
    
    class Person {
        private int id;
        private String name;
    
        public Person() {
        }
    
        public Person(String name) {
            super();
            this.name = name;
        }
    
        public Person(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "编号" + id + "	姓名" + name;
        }
    
        public void add(int i, int j) {
            System.out.println("i+j=" + (i + j));
        }
    
        private void add2(int i, int j) {
            System.out.println("i+j=" + (i + j));
        }
    
        public int add3(int i, int j) {
            return i + j;
        }
    }
    
    public class ReflectTest {
    
        public static void main(String[] args)
                throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
                SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
            {
                System.out.println("练习1:动态获取类类型的名称");
                // 模拟参数args[0]为className
                // 注意:完整的className包含包名
                String className = "java.lang.String";
                // 1 动态获取类类型对象及其名称
                System.out.println("完整类名:" + Class.forName(className).getName());
                System.out.println("简单类名:" + Class.forName(className).getSimpleName());
            }
            {
                System.out.println("
    练习2:动态加载类类型,动态绑定多个类对象的方法");
                String className = "d518Reflect.Excel";
                // 加载 类
                Class<?> class1 = Class.forName(className);
                // 创建 类对象
                Object object = class1.newInstance();
                // 对象还原
                Office office = (Office) object;// Office 和 Excel间是实现关系,若没有关系,报错
                // 动态绑定
                office.start();
            }
            {
                System.out.println("
    练习3:遍历 构造器");
                String className = "d518Reflect.Person";
                Class<?> class1 = Class.forName(className);
                Constructor<?>[] con = class1.getDeclaredConstructors();
                for (Constructor<?> tem : con) {
                    System.out.print("构造器名称:" + tem.getName() + "(");
                    Class<?>[] types = tem.getParameterTypes();
                    for (Class<?> temp : types) {
                        System.out.print(" " + temp.getSimpleName() + " ");
                    }
                    System.out.println(")");
                }
            }
            {
                System.out.println("
    练习4:遍历 属性");
                String className = "d518Reflect.Person";
                Class<?> class1 = Class.forName(className);
                Field[] fields = class1.getDeclaredFields();
                for (Field field : fields) {
                    System.out.println(field.getType().getSimpleName() + "	" + field.getName());
                }
            }
            {
                System.out.println("
    练习5:遍历 方法");
                String className = "d518Reflect.Person";
                Class<?> class1 = Class.forName(className);
                Method[] ms = class1.getDeclaredMethods();
                for (Method md : ms) {
                    System.out.print(md.getName() + "(");
                    Class<?>[] types = md.getParameterTypes();
                    for (Class<?> type : types) {
                        System.out.print(" " + type.getSimpleName() + " ");
                    }
                    System.out.println(")");
    
                }
            }
            {
                System.out.println("
    练习6:构造器 反射");
                String className = "d518Reflect.Person";
                Class<?> class1 = Class.forName(className);
                Object obj = class1.newInstance();// 默认构造器 直接使用
                Constructor<?> con = class1.getDeclaredConstructor(String.class);// 1
                                                                                    // 带参
                Object obj2 = con.newInstance("张三");// 2 对象
                System.out.println(obj);
                System.out.println(obj2);
            }
            {
                System.out.println("
    练习7:属性 反射");
                String className = "d518Reflect.Person";
                Class<?> class1 = Class.forName(className);
                Field field = class1.getDeclaredField("id");
                Object obj1 = class1.newInstance();
                System.out.println("修改前" + obj1);
                field.setAccessible(true);
                Object value = 8;
                field.set(obj1, value);
                System.out.println(obj1);
            }
            {
                System.out.println("
    练习8:方法 反射");
                String className = "d518Reflect.Person";
                Class<?> class1 = Class.forName(className);
                Object obj = class1.newInstance();
                Method add = class1.getDeclaredMethod("add", int.class, int.class);
                add.invoke(obj, 2, 3);// 调用方法时,指明 对象
            }
            {
                System.out.println("
    练习9:数组 反射");
                // // 一维数组
                // Class<?> class1 = int.class;//指定类型
                // Object arr = Array.newInstance(class1, 5);//创建数组
                // System.out.println("一维数组:");
                // for (int i = 0; i < 5; i++) {
                // int j = i * 3;
                // Array.set(arr, i, j);//设置值
                // System.out.print(Array.get(arr, i)+" ");//获取值
                // }
                // 多维数组
                // 准备一个指定大小的二维数组
                int size[] = new int[] { 5, 10 };
                // 准备数组存放数组的类型
                Class type = int.class;
                Object array = Array.newInstance(type, size);
                // 设置值
                Array.set(Array.get(array, 0), 0, 66);
                // 访问值
                System.out.println(Array.get(Array.get(array, 0), 0));
            }
    
        }
    
    }
  • 相关阅读:
    项目开发目录
    语法 部分
    time模块
    文件 部分
    二分法
    函数 部分
    递归
    模块 部分
    稀疏数组
    Java中使用foreach遍历数组
  • 原文地址:https://www.cnblogs.com/qixiawentang/p/5504430.html
Copyright © 2020-2023  润新知