反射相关/定义/为什么用反射/优缺点/应用场景/demo

反射

什么是反射?

反射就是程序运行状态中,对于任意一个类,能够知道这个类的所有属性和方法,对于任意一个对象,能够调用方法/获取属性。

就是反射可以通过指定的类名来获取类的信息。

首先要知道一个知识点,类加载过程:

  • 首先,一个.java文件经过编译成功后,得到一个.class文件
  • 初始化操作的时候,会将这个.class文件通过类加载器加载到jvm中
  • 加载到jvm中又分了好几个步骤,包括加载,连接和初始化
  • 加载的时候,会再Java堆中创建一个java.lang.Class类的对象,这个Class对象代表着类的相关信息
为什么要学习反射?

参考链接:关于反射挺不错的讲解

反射的学习

其实就是对Class类和java.lang.reflect的学习

如何获取class对象

//1. 通过 Class.forName(String className) 来获取class对象
Class<?> clazz = Class.forName("Solution");
//2. 通过 类名.class获取class对象
Class<Solution> solutionClass = Solution.class;
//3. 通过 实例对象.getClass()来获取class对象
Solution solution = new Solution();
Class<? extends Solution> solutionClass1 = solution.getClass();

运行期间,一个类只能有一个Class对象产生

class Solution{

    public void sayHello(){
        System.out.println("hello");
    }

    public static void main(String[] args){
        try {
            Class<Solution> solutionClass = Solution.class;
            Class<?> solution = Class.forName("Solution");
            System.out.println(solution.hashCode());
            System.out.println(solutionClass.hashCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

验证(输出结果):

685325104
685325104

java.lang.reflect包下的主要类库就是下面三个:

  • Filed:可以使用get()和set()方法读取和修改Filed对象关联的字段
  • Method:可以使用invoke()方法调用与Method对象关联的方法
  • Constructor:可以使用Constructor创建对象
反射优缺点
  • 优点:可扩展,在运行时加载类,更灵活
  • 缺点:一系列解释性操作,通过jvm实现,性能开销大
反射应用场景
  • jdbc中连接数据库时候,反射加载驱动程序

    Class.forNmae("com.mysql.jdbc.Driver");
    
  • Spring中 IOC容器根据配置文件信息 --> 获取类文件信息 --> 反射创建bean实例,并反射调用Set方法设置属性

  • SpringMVC自动识别前台传递过来的参数,自动组装成JavaBean,这也是通过反射来实现的

反射的Demo

详情见我另一篇博客:反射demo

  • 通过反射调用方法

    import java.lang.reflect.Method;
    
    class Solution{
    
        public static void main(String[] args){
    
            try {
                // 通过反射调用类的方法
                // 获取class对象
                Class<?> clazz = Class.forName("com.hou.study.Book");
                // 使用java.lang.reflect包下的Method类库
                Method method = clazz.getMethod("sayHello", String.class, int.class);
                // 使用invoke调用与method相关联的方法
                method.invoke(clazz.newInstance(),"Java",20);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    // 输出结果
    // hello!,this book name is Javaand price is 20
    
  • 通过反射设置属性

    import java.lang.reflect.Field;
    
    class Solution{
    
        public static void main(String[] args){
    
            try {
                // 获取class对象
                Class<?> clazz = Class.forName("com.hou.study.Book");
                Object instance = clazz.newInstance();
                // 此时用到了 java.lang.reflect 的 Filed类库
                Field field = clazz.getDeclaredField("name");
                // 设置取消权限检查,可以set
                field.setAccessible(true);
                field.set(instance,"Java");
                System.out.println(instance);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    // 输出结果
    // Book{name='Java', price=0}
    
  • 通过反射构造实例化对象

    import java.lang.reflect.Constructor;
    
    class Solution{
    
        public static void main(String[] args){
            try {
                // 获取class对象
                Class<?> clazz = Class.forName("com.hou.study.Book");
                // 获取带参构造方法 用到了constructor类库
                Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
                Object java = constructor.newInstance("Java", 20);
                System.out.println(java);       // Book{name='Java', price=20}
                // 获取无参构造方法
                Constructor<?> constructor1 = clazz.getConstructor();
                Object o = constructor1.newInstance();
                System.out.println(o);      // Book{name='null', price=0}
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值