【Java基础】反射相关面试题

1. 什么是Java反射机制

Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;
并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方
法的功能成为 Java 语言的反射机制。

2. 反射的优缺点

优点:

  1. 提高了灵活性,可以在运行时动态操作类和对象。
  2. 支持框架开发,很多框架(如 Spring)大量使用反射来进行依赖注入和动态代理等操作。

缺点:

  1. 性能开销较大,反射操作通常比直接调用慢。
  2. 代码安全性降低,反射可以绕过访问修饰符(如 private),可能导致不安全操作。
  3. 代码可读性和维护性降低,反射代码通常较为复杂,不易理解和调试。

3. 反射的应用场合

  1. 框架开发: 许多框架(如Spring、Hibernate)广泛使用反射来扫描和处理注解、注入依赖、管理Bean的生命周期等。通过反射,框架可以动态地发现和使用应用程序的类和方法。

  2. 对象序列化和反序列化:在对象序列化(如Java的JAXB或Jackson)过程中,反射用于访问对象的字段和方法,以将对象转换为字节流或其他格式,或者从这些格式重建对象。

  3. 代码生成和动态代理:反射用于生成代理类和动态字节码。例如,Java中的java.lang.reflect.Proxy类可以在运行时创建接口的实现。

  4. 测试工具和框架: 许多测试框架(如JUnit)使用反射来发现和调用测试方法,注入测试数据等。

4. 反射常用API

  1. Class 类:反射的核心类,可以获取类的属性,方法、等信息以及new实例等等。java.lang包下的
  2. Field 类:Java.lang.reflec 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性
    值。java.lang.reflect.Field
  3. Method 类: Java.lang.reflec 包中的类,表示类的方法,它可以用来获取类中的方法信息或
    者执行方法。java.lang.reflect.Method
  4. Constructor 类: Java.lang.reflec 包中的类,表示类的构造方法,可以获取不同参数,不同权限的构造方法、还可以new实例。java.lang.reflect.Constructor
/*
        Class类中用于获取构造方法的方法
            Constructor<?>[] getConstructors()                                返回所有公共构造方法对象的数组
            Constructor<?>[] getDeclaredConstructors()                        返回所有构造方法对象的数组
            Constructor<T> getConstructor(Class<?>... parameterTypes)         返回单个公共构造方法对象
            Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造方法对象

        Constructor类中用于创建对象的方法
            T newInstance(Object... initargs)                                 根据指定的构造方法创建对象
            setAccessible(boolean flag)                                       设置为true,表示取消访问检查
        */

/**
         *  Class类中用于获取成员变量的方法
         *             Field[] getFields():                返回所有公共成员变量对象的数组
         *             Field[] getDeclaredFields():        返回所有成员变量对象的数组
         *             Field getField(String name):        返回单个公共成员变量对象
         *             Field getDeclaredField(String name):返回单个成员变量对象
         *
         *        Field类中用于创建对象的方法
         *             void set(Object obj, Object value):赋值
         *             Object get(Object obj)              获取值
         */

 /**
         * Class类中用于获取成员方法的方法
         *             Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
         *             Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
         *             Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
         *             Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
         *
         *        Method类中用于创建对象的方法
         *             Object invoke(Object obj, Object... args):运行方法
         *             参数一:用obj对象调用该方法
         *             参数二:调用方法的传递的参数(如果没有就不写)
         *             返回值:方法的返回值(如果没有就不写)
         *
         *         获取方法的修饰符
         *         获取方法的名字
         *         获取方法的形参
         *         获取方法的返回值
         *         获取方法的抛出的异常
         */

5. 获取class对象的三种方法

  1. Class.forName(“全类名”)
  2. 类名.class
  3. 对象.getClass();

6. 利用反射创建对象的两种方式

  1. Class 对象的 newInstance() : 使用 Class 对象的 newInstance()方法来创建该 Class 对象对应类的实例,但是这种方法要求该 Class 对象对应的类有默认的空构造器。
  2. 调用 Constructor 对象的 newInstance():
//获取 Person 类的 Class 对象
Class clazz = Class.forName("reflection.Person");
//使用.newInstane 方法创建对象
Person p = (Person) clazz.newInstance();
//获取构造方法并创建对象
Constructor c = clazz.getDeclaredConstructor(String.class,String.class,int.class);
//创建对象并设置属性13/04/2018
Person p1 = (Person) c.newInstance("李四","男",20);

7. 反射性能差的原因

反射的性能相对于直接调用来说要差一些,主要原因如下:

  1. 安全检查:反射在运行时需要进行大量的安全检查(如访问控制检查),这会导致额外的开销。

  2. 动态解析:反射需要在运行时解析类、方法和字段信息,而这些操作在正常调用中是在编译时完成的。动态解析会带来额外的性能开销。

  3. 无优化:JVM 对于反射调用的优化能力有限。JIT(Just-In-Time)编译器不能对反射调用进行同样级别的优化,因为反射调用的目标在编译时是未知的。

  4. 缺少内联:常规方法调用可以被 JVM 内联以减少方法调用的开销,而反射调用由于其动态性,无法享受这种优化。

附录

  1. Java反射复习 http://t.csdnimg.cn/2gllk
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boy快快长大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值