反射

反射是框架设计的灵魂。将类的各个组成部分封装为其他对象,这就是反射机制。运行程序的时候,我们实际上加载的是class文件。是由"类加载器"将class文件加载进内存。class文件进入到内存中,字节码文件对象,就是由 Class 类来描述这个字节码文件对象的。字节码文件对象是一个大的概念,是class文件被加载进内存中形成的。那么一个类中,还有成员变量,构造方法,成员方法。我们又用三个不同的类,分别去描述成员变量,构造方法,成员方法。

如何获取class文件对象?
  1. Class.forName("全类名")

  2. 类名.class

  3. 对象.getClass():getClass()

如何获取class文件对象中的成员变量并对其进行赋值?

Field[] getFields() : 获取所有public修饰的成员变量

Field getField(String name) : 获取指定名称的 public修饰的成员变量

Field[] getDeclaredFields() : 获取所有的成员变量,不考虑修饰符

Field getDeclaredField(String name) : 获取指定的成员变量,不考虑修饰符

//获得到这个类的字节码文件对象
Class cls = Class.forName("com.itheima.demo1.Student");
//通过字节码文件的整体来获取其中某一个成员变量
Field name = cls.getDeclaredField("name");
//暴力反射。
name.setAccessible(true);
//设置值,获取值。
Student s = new Student();
name.set(s,"张三");
Object o = name.get(s);
System.out.println(o);
如何获取class文件对象中的构造方法并创建这个类的对象?

Constructor<?>[] getConstructors() : 获得所有public修饰的构造方法
Constructor<T> getConstructor(参数类型.class) : 获得public修饰的指定构造
Constructor<T> getDeclaredConstructor(参数类型.class) : 获取所有构造方法,无视修饰符
Constructor<?>[] getDeclaredConstructors() : 获得指定构造,无视修饰符

        //通过有参构造来创建对象
        Class cls1 = Class.forName("com.itheima.demo1.Student");
        Constructor constructor = cls1.getConstructor(String.class, int.class);
        Object o1 = constructor.newInstance("张三", 23);
        System.out.println(o1);

        //通过无参构造来创建对象
        Class cls2 = Class.forName("com.itheima.demo1.Student");
        Constructor constructor2 = cls2.getConstructor();
        Object o2 = constructor2.newInstance();
        System.out.println(o2);
        
        //简化写:直接通过字节码文件对象获取无参构造
        Class cl3 = Class.forName("com.itheima.demo1.Student");
        Object o3 = cls3.newInstance();
        System.out.println(o3);
如何获取class文件对象中的成员方法并进行调用?

Method[] getMethods() : 获得所有public修饰的成员方法
Method getMethod(方法名, 参数类型.class):获得public修饰的指定成员方法
Method[] getDeclaredMethods() : 获取所有成员方法,无视修饰符
Method getDeclaredMethod(方法名, 参数类型.class) : 获得指定成员方法,无视修饰符

Class cls = Class.forName("com.itheima.demo1.Student");
Method method = cls.getDeclaredMethod("eat");
Student s = new Student();
method.invoke(s);
示例:
class Demo{
    public static void main(String [] args){
        //1.加载配置文件
        //1.1创建Properties对象
        Properties pro = new Properties();
        //1.2加载配置文件,转换为一个集合
        //1.2.1获取class目录下的配置文件]
        ClassLoader classLoader = 当前类名.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("pro.properties");//当前配置文件在src目录下
        pro.load(is);

        //2.获取配置文件中定义的数据
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");

        //3.加载该类进内存
        Class cls = Class.forName(className);
        //4.创建对象
        Object obj = cls.newInstance();
        //5.获取方法对象
        Method method = cls.getMethod(methodName);
        //6.执行方法
        method.invoke(obj);
    }
}   

转载于:https://www.cnblogs.com/ccav1/p/10046649.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值