反射

反射
Class类
获取文件字节码对象的三种方法
public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取文件字节码对象的三种方法
        //Class类:描述文件对象的类
        //1.通过对象获取
        Person p=new Person();
        Class c=p.getClass();
        System.out.println(c);
        //2.通过类名获取
        Class c1=Person.class;
        System.out.println(c1);
        System.out.println(c==c1);//证明了字节码文件对象在堆里就一个
        System.out.println(c.equals(c1));
        //3.通过Class类中的静态方法forName(完整的包名+类名)获取
        Class c2=Class.forName("com.oracle.demo02.Person");
        System.out.println(c2);
    }
}

 

通过反射获取构造方法并使用
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//Class类:描述文件对象
//Constructor类:描述构造方法的类
//Method类:描述方法的类
//Filed类:描述变量的类
public class Demo02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //获取Person的字节码文件对象
        Class c=Class.forName("com.oracle.demo02.Person");//静态代码块
        //获取该类中所有公共的构造方法   数组
        Constructor[] cons=c.getConstructors();
        for(Constructor con:cons){
            System.out.println(con);
        }
        //获取该类中的公共空参构造
        Constructor con1=c.getConstructor();
        //使用构造方法对象去创建Person对象
        Object obj=con1.newInstance();//这是个多态
        System.out.println(obj);
        Person p=(Person)obj;//强转调用自己独有的方法
        p.eat();
        //获取该类中的公共有参构造并使用
        Constructor con2=c.getConstructor(String.class,int.class);
        Object obj2=con2.newInstance("飒",1);
        System.out.println(obj2);
        //反射获取空参构造方法并运行的快速方式
        //前提:1.被反射的类必须有空参构造方法
        //2.该方法必须是public修饰
        Object obj3=c.newInstance();//是Class类中的方法   不再是构造方法里的了
        System.out.println(obj3);
    }
}

 

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
        method1();
        //method2();
        //method3();
    }
    public static void method1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        Class c=Class.forName("com.oracle.demo02.Person");
        //反射获得Person类中所有的构造方法
        /*Constructor[] cons=c.getDeclaredConstructors();
        for(Constructor con:cons){
            System.out.println(con);
        }*/
        //反射获得私有的有参构造
        Constructor con=c.getDeclaredConstructor(String.class);
        //暴力反射   破坏了程序的封装性,安全性    可以下面方法暴力反射  但不推荐
        //调用父类的方法避免java语言的访问检查      
        con.setAccessible(true);
        Object obj=con.newInstance("李四");
        System.out.println(obj);
    }
通过反射获取成员变量并使用
    public static void method2() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{
        //反射获取成员变量并改值
        Class c=Person.class;
        Field[] fileds=c.getDeclaredFields();
        for(Field f:fileds){
            System.out.println(f);
        }
        //获取Person类中的公共成员变量并改值
        //快速创建一个Person对象
        Object obj=c.newInstance();
        Field field=c.getField("name");
        field.set(obj, "张三");
        System.out.println(obj);
    }

 

通过反射获取成员方法并使用
    public static void method3() throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
        //反射成员方法,并调用
        Class c=Person.class;
        //快速创建一个Person对象
        Object obj=c.newInstance();
        //获取所有的方法
        /*Method[] methods=c.getDeclaredMethods();
        for(Method m:methods){
            System.out.println(m);
        }*/
        //获取公共有参构造并调用
        Method method=c.getMethod("sleep",String.class);
        method.invoke(obj,"李四");
    }
}

 

反射练习
泛型擦除
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
//泛型擦除  不推荐 了解
public class Demo04 {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        ArrayList<Integer> arr=new ArrayList<Integer>();
        arr.add(1);
        //获取字节码文件对象
        Class c=arr.getClass();
        Method method=c.getMethod("add",Object.class);
        method.invoke(arr,"你好");
        System.out.println(arr);//[1, 你好]
    }
}
反射配置文件
public class Person {
    public void eat(){
        System.out.println("人");
    }
}
public class Student {
    public void study(){
        System.out.println("学生学习");
    }
}
public class Worker {
    public void work(){
        System.out.println("工人");
    }
}

#ClassName=com.oracle.demo03.Person
#MethodName=eat
#修改这一部分就OK了
ClassName=com.oracle.demo03.Worker
MethodName=work   
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class Demo01 {
    //1.准备配置文件,Properties 键值对方式存储
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //2.IO流去读取配置文件中的键值对   Reader
        FileReader fr=new FileReader("config.properties");
        //3.将文件中的键值对存储到集合中的Properties中
        Properties pro=new Properties();
        pro.load(fr);
        fr.close();
        //4.从集合中获取类名和方法名
        String className=pro.getProperty("ClassName");
        String methodName=pro.getProperty("MethodName");
        //5.反射获取指定类的class文件对象
        Class c=Class.forName(className);
        //快速创建指定类对象
        Object obj=c.newInstance();
        //获取指定的方法
        Method method=c.getMethod(methodName);
        //6.运行指定的方法
        method.invoke(obj);//工人
    }
}

 

posted @ 2019-01-10 16:10  帅涛  阅读(198)  评论(1编辑  收藏  举报