反射,反射配置文件

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);
    }
}

猜你喜欢

转载自www.cnblogs.com/quanjunkang/p/10694610.html