什么是反射?可以解决什么问题?

什么是反射?可以解决什么问题?

什么是反射?
反射是指程序在运行状态中,可以对任意一个类,都能够获取并调用到这个类的所有属性和方法。

反射是一种能力,一种在程序运行时,动态获取当前类对象的所有属性和方法的能力,可以动态执行方法,给属性赋值等操作的能力。

Class代表的就是所有的字节码对象的抽象,类反射,让我们的java程序具备动态性,这种动态获取类信息及调用对象方法的功能称为反射。
可以破坏单例,除了枚举以外。

在java中,Class类就是关键API

public class Reflection {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        //1.以class对象为基础
        Class<?> clazz = Class.forName("com.hgz.reflection.Student");
        System.out.println(clazz);
        //2.类中每一部分,都有对应的类与之匹配
        //表示属性的类
        Field nameField =
                clazz.getField("name");
        //表示方法的类
        Method helloMethod = clazz.getDeclaredMethod("hello", String.class);
        //表示构造方法的类
        Constructor<?>[] constructors = clazz.getConstructors();
    }
}

这种能力带来很多的好处,在我们的许多框架的背后实现上,都采用了反射的机制来实现动态效果。

框架是提供一种编程的约定。

比如@Autowrie 就能实现自动注入

@Autowrie

private IUserService userService;

注解的解析程序,来扫描当前的包下面有哪些属性加了这个注解,一旦有这个注解,就要去容器里面获取对应的类型的实现,然后给这个属性赋值。

如实现一个IOC容器

反射常见面试题

1. 什么是Java反射?

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

2. Java反射创建对象效率高还是通过new创建对象的效率高?

解析:
通过new创建对象的效率比较高。通过反射时,需要先查找类资源,使用类加载器创建,过程比较繁琐,所以效率较低。

3. 获取Class对象的方法有哪些?

解析:
获取Class对象有以下四种方法:

Class.forName(“类的路径”)
类名.class
对象名.getClass()
基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。

4. 实现Java反射的类有哪些?

Class:表示正在运行的Java应用程序中的类和接口,所有获取对象的信息都需要Class类来实现。
Field:提供有关类和接口的属性信息,以及对它的动态访问权限。
Constructor:提供关于类的单个构造方法的信息以及它的访问权限。
Method:提供类或接口中某个方法的信息。

5. 反射机制的优缺点是什么?

优点
能够运行时动态获取类的实例,提高灵活性。
与动态编译结合,例如加载数据库驱动等。

缺点
使用反射性能较低,需要解析字节码,将内存中的对象进行解析。
破坏了封装性,可能导致安全问题。

6. 如何提高反射的性能?

使用setAccessible(true)关闭JDK的安全检查来提升反射速度。
多次创建一个类的实例时,使用缓存可以加快反射速度。
使用第三方工具类,如ReflflectASM,通过字节码生成的方式加快反射速度。

7. Java反射的主要作用是什么?

在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具有的成员变量和方法。
在运行时调用任意一个对象的方法。

Java开发中,非法反射访问警告通常发生在使用反射机制访问一些非public的成员(如字段、方法、构造器等)时。因为这些成员并不是公开的API,所以它们可能在未来的Java版本中发生变化,从而导致反射代码失效。Java为了提醒开发者这种情况的存在,会发出警告。 解决这类警告的常见方法包括: 1. **显式添加警告忽略**:在使用反射的代码附近添加注解`@SuppressWarnings("unchecked")`或者`@SuppressWarnings("serial")`,以忽略特定的警告。这种方法的缺点是可能会隐藏掉真正需要关注的警告,因此需要谨慎使用。 ```java @SuppressWarnings("unchecked") public void myMethod() throws Exception { Field field = MyClass.class.getDeclaredField("fieldName"); field.setAccessible(true); // 其他反射操作... } ``` 2. **使用反射API的替代方案**:如果可能,避免直接使用反射API,而是寻找库提供的替代方法。有些第三方库提供了更加安全和方便的方式来访问特定的字段或方法。 3. **修改访问权限**:如果代码是自己维护的,可以考虑将需要访问的成员声明为public,或者至少是protected或default(包内访问权限),这样就无需违反访问权限规则。 4. **使用Java模块系统**:如果项目使用的是Java 9或更高版本,可以考虑使用模块化来控制对包的可见性,而不是使用反射。通过模块的exports和opens语句,可以更精细地控制哪些包和类是可供反射访问的。 5. **确保反射的正确性和安全性**:在进行反射操作之前,应该检查运行时环境是否支持这种操作,并且确认反射不会破坏封装性或导致安全漏洞。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值