• 反射,反射配置文件


    1  Class类

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    1.1  获取Class对象的三种方式:

    public class Person {
        private String name;
        public int age;
        static{
            System.out.println("静态代码块");
        }
        public     Person(){
            System.out.println("空参构造");
        }
        public Person(String name,int age){
            this.name=name;
            this.age=age;
            System.out.println("Person(String name,int age)");
        }
        private Person(String name){
            this.name=name;
            System.out.println("Person(String name)");
        }
        public void eat(){
            System.out.println("公共空参方法");
        }
        public void sleep(String name){
            System.out.println("公共有参方法");
        }
        public void smoke(){
            System.out.println("私有空参构造");
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
    }
    public class Demo01 {
        public static void main(String[] args) throws ClassNotFoundException {
            //1.通过getClass方法获取, 通过对象获取
            Person p=new Person();
            Class c1=p.getClass();
            System.out.println(c1);
            //2.通过类名获取
            Class c2=Person.class;
            System.out.println(c2);
            System.out.println(c1==c2);
            System.out.println(c1.equals(c2));
            //3.通过完整的包名+类名获取
            Class c3=Class.forName("com.oracle.demo03.Person");
            System.out.println(c3);
        }
    }

    2     通过反射获取构造方法并使用

    在反射机制中,把类中的成员(构造方法、成员方法、成员变量)都封装成了对应的类进行表示。其中,构造方法使用类Constructor表示。可通过Class类中提供的方法获取构造方法:

    public class Demo02 {
        //构造方法 Constructor
        //成员变量 Field
        //成员方法 Method
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            //反射获取构造方法
            //1.获取Person.Class文件对象
            Class c=Class.forName("com.oracle.demo03.Person");
            //获取所有公共的构造方法(数组)
            /*Constructor[]cons=c.getConstructors();
            //遍历
            for(Constructor con:cons){
                System.out.println(con);
            }*/
            //获取某个公共构造方法
            /*Constructor con1=c.getConstructor(String.class,int.class);
            System.out.println(con1);
            //通过构造方法创建对象
            Object obj=con1.newInstance("张三",18);
            System.out.println(obj);*/
            //获取所有构造方法数组
            /*Constructor[]cons=c.getDeclaredConstructors();
            for(Constructor con:cons){
                System.out.println(con);
            }*/
            //获取某个私有构造方法
            Constructor con=c.getDeclaredConstructor(String.class);
            //System.out.println(con);
            //暴力反射
            con.setAccessible(true);
            Object obj=con.newInstance("熊大");
            System.out.println(obj);
        }
    }

    3   通过反射获取成员变量和成员方法并使用

    在反射机制中,把类中的成员变量使用类Field表示。可通过Class类中提供的方法获取成员变量:

    在反射机制中,把类中的成员方法使用类Method表示。可通过Class类中提供的方法获取成员方法:

    public class Demo01 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException {
            //获取字节码文件对象
            Class c=Class.forName("com.oracle.demo01.Person");
            //获取所有的成员变量
            /*Field[]fields=c.getDeclaredFields();
            //遍历
            for(Field field:fields){
                System.out.println(field);
            }*/
            //获取某个成员变量并赋值
            /*Field field=c.getDeclaredField("age");
            Object obj=new Person();
            field.set(obj, 18);
            System.out.println(obj);*/
            //获取所有成员方法
            /*Method[]methods=c.getDeclaredMethods();
            //遍历
            for(Method method:methods){
                System.out.println(method);
            }*/
            //获取单个成员方法
            Method method=c.getMethod("sleep", String.class);
            //调用方法
            Object obj=c.newInstance();    
            method.invoke(obj, "张三");
            
        }
    }

    4  反射练习

    4.1 泛型擦除

    思考,将已存在的ArrayList<Integer>集合中添加一个字符串数据,如何实现呢?

    其实程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为泛型的擦除。那么,我们可以通过反射技术,来完成向有泛型约束的集合中,添加任意类型的元素

    public class Demo02 {
        public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
            //泛型擦除
            ArrayList<Integer>arr=new ArrayList<Integer>();
            //获取ArrayList的字节码文件对象
            Class c=arr.getClass();
            //通过反射的方式获取add方法
            Method add=c.getMethod("add", Object.class);
            add.invoke(arr, "aaa");
            System.out.println(arr);
        }
    }

    4.2   反射配置文件

    通过反射配置文件,运行配置文件中指定类的对应方法

    读取properties文件中的数据,通过反射技术,来完成Person对象的创建

    public class Demo01 {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
            //明确配置文件的路径
            FileReader fr=new FileReader("src/com/oracle/demo02/config.properties");
            //创建Properties集合
            Properties pro=new Properties();
            //从配置文件中读取键值对到集合中
            pro.load(fr);
            //从集合中获取完整的包名+类名
            String ClassName=pro.getProperty("ClassName");
            //获取方法名
            String MethodName=pro.getProperty("MethodName");
            //通过反射获取字节码文件对象
            Class c=Class.forName(ClassName);
            //创建对象
            Object obj=c.newInstance();
            //获取方法
            Method method=c.getMethod(MethodName);
            //调用方法
            method.invoke(obj);
        }
    }
  • 相关阅读:
    管理者应有意识地提高以下八项能力
    weblogic调优
    嵌入式软件的基本测试方法
    LoadRunner Interview Questions
    测试类型概念解析
    要是下次他们放手机时戴了手套怎么办?
    外企面试智力题
    贴张我家养的狗狗们的照片!
    一样一句
    软件测试工程师面试英语
  • 原文地址:https://www.cnblogs.com/quanjunkang/p/10694610.html
Copyright © 2020-2023  润新知