反射(尚硅谷视频笔记)

反射:框架设计的灵魂
*框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
*反射:将类的各个组成部分封装为其他对象,这就是反射机制
好处:
    1.可以在程序运行过程中,操作这些对象。
    2.可以解耦,提高程序的可扩展性。
获取class对象的方式:
    1.Class.forName(“全类名"):将字节码文件加载进内存,返回class对象
        多用于配置文件,将类名定义在配置文件中。读取文件,返回Class对象
    2.类名.class:通过类名的民性class获取
        多用于参数的传递
    3.对象.getclass0:getclass()方法在object类中定义着。
        多用于对象的获取字节码的方式
    结论:
        同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

package Test.reflect;

public class ReflectDemo1 {
    /**
     * 获取Class对象的方式:
     * 1.获取Class.forName("全类名");将字节码文件加载进内存,返回Class
     * 2.类名.class:通过类名的属性class获取
     * 3.对象.getClass():getClass()方法在Object类中定义
     */
    public static void main(String[] args) throws Exception {
        //1.Class.forName("全类名");
        Class cls1 = Class.forName("Test.reflect.Person");
        System.out.println(cls1);
        //2.类名.class
        Class personClass = Person.class;
        System.out.println(personClass);
        //3.对象名.getClass();
        Person person=new Person();
        Class cls2 = person.getClass();
        System.out.println(cls2);
        //比较,地址用==
        System.out.println(cls1==cls2);
        System.out.println(cls1==personClass);
    }
}

Class对象功能:
        获取功能:
            1.获取成员变量们
                Field[] getFields()
                Field getField(String name)
                Field[] getDeclaredFields()
                Field getDeclaredField(String name)
            Field:成员变量
                操作:
                    1,设置值
                        void set(object obj,object value)
                    2.获取值
                        get(object obj)
                    3.忽略访问权限修饰符的安全检当
                        setAccessible(true):暴力反射

public static void main(String[] args) throws Exception {
    Class personClass = Person.class;
    Field[] fields = personClass.getFields();//只能获取public修饰的成员变量
    for(Field field:fields){
        System.out.println(field);
    }
    Person person1 = new Person();
    Field a = personClass.getField("a");//只能获取public修饰的成员变量
    Object o1 = a.get(person1);
    System.out.println(o1);//null
    //设置对象
    a.set(person1,"张三");
    System.out.println(person1);
    Field[] declaredFields = personClass.getDeclaredFields();//能获取所有类型
    for(Field declaredField:declaredFields){
        System.out.println(declaredField);
    }
    Field b = personClass.getDeclaredField("b");//能获取所有类型
    Person person2 = new Person();
    b.setAccessible(true);//暴力反射
    Object o2 = b.get(person2);
    System.out.println(o2);
    b.set(person2,"李四");
    System.out.println(person2);
}

2.获取构造方法们
                constructor<?>[] getconstructors()
                constructor<T> getconstructor(类<?>... parameterTypes)
                constructor<T> getDeclaredconstructor(类<?>... parameterTypes)
                constructor<?>[] getDeclaredconstructors()
            constructor:构造方法
                创建对象:
                    T newInstance(0bject... initargs)
                    如果使用空参数构造方法创建对象,操作可以简化:class对象的newInstance方法

public static void main(String[] args) throws Exception {
    Class personClass = Person.class;
    Constructor constructor = personClass.getConstructor(String.class, int.class);
    System.out.println(constructor);
    //创建对象(有参数)
    Object person = constructor.newInstance("张三",12);
    System.out.println(person);
    Constructor constructor1 = personClass.getConstructor();
    System.out.println(constructor1);
    //创建对象(空参)方法一:
    Object person1 = constructor1.newInstance();
    System.out.println(person1);
    //方法二:
    Object o = personClass.newInstance();
    System.out.println(o);
}

3.获取成员方法们:
                Method[] getMethods()
                Method getMethod(string name,类<?>... parameterTypes)
                Method[] getDec laredMethods()
                 Method getDeclaredMethod(string name,类<?>... parameterTypes)
            4.获取类名
                String getName()
            Pethod:方法对象
                执行方法:
                    object invoke(object obj,Object. . . args)
                获取方法名称:
                    string getName :获取方法名

public static void main(String[] args) throws Exception {
        Class personClass = Person.class;
        Person person = new Person();
        Method eat = personClass.getMethod("eat");
        System.out.println(eat);
        Method method = personClass.getMethod("eat",String.class);
        method.invoke(person, "food");
        //获取public方法
        Method[] methods = personClass.getMethods();
        for(Method method1:methods){
            System.out.println(method1);
//            method1.setAccessible(true);//暴力反射
            //获取方法名
            String name = method1.getName();
            System.out.println(name);
        }
        //获取类名
        String name = personClass.getName();
        System.out.println(name);
    }

    案例:
        需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
    实现:
        1.配置文件
        2.反射
    步骤:
        1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
        2.在程序中加载读取配置文件
        3.使用反射技术来加载类文件进内存
        4.创建对象
        5.执行方法

className=Test.reflect.Student
methodName=sleep
package Test.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //1.加载配置文件
        //1.1创建Properties对象
        Properties properties = new Properties();
        //1.2加载文件,转换为一个集合
        //1.2.1获取class目录下的配置文件
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        InputStream resourceAsStream = classLoader.getResourceAsStream("pro.properties");
        properties.load(resourceAsStream);
        //2.获取配置文件中定义的数据
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");
        //3.加载该类进内存
        Class aClass = Class.forName(className);
        //4.创建对象
        Object o = aClass.newInstance();
        //5.获取对象方法
        Method method = aClass.getMethod(methodName);
        //6.执行方法
        method.invoke(o);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值