(1)Java虚拟机反射机制的定义?
- Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
(2)谈谈你对Java虚拟机反射机制的理解?
- Java的反射机制可以理解为,虚拟机在运行期间可以将运行在自己内存中的的类反编译为.class文件,然后通过类加载器加载该字节码文件,这样我们就得到在运行期间一个完整的类。有什么用呢?这就不得不提到多态实现的三种形式。
- java中实现多态的形式主要有三种:向上转型,抽象类实现,接口类实现。我们是不可以直接实例化接口和抽象类,但是这类对象我们可以通过其实现类进行实例化。因此这三种方式实例化的对象数据类型都需要在运行时才能够确定,我们想要用这类对象的内部方法,那必须借助反射机制,反射机制诞生之前,我们不能直接获取这类对象的内部信息。但是反射机制诞生之后,我们可以在运行时,通过反射,我们可以实时动态的获取这些对象的具体的数据类型内部信息。如果直接new的话,无法实现解耦。
(3)上文谈到类加载器,可以解释以下双亲委派机制
- 如果有人想替换系统级别的类:String.java。篡改它的实现,在这种机制下这些系统的类已经被Bootstrap classLoader加载过了(为什么?因为当一个类需要加载的时候,最先去尝试加载的就是BootstrapClassLoader),所以其他类加载器并没有机会再去加载,从一定程度上防止了危险代码的植入。
(3)如何实现类类加载器加载后的完整类与接口进行对接而不是New/动态代理机制
详解
- 通过Proxy类中的getProxyClass获得代理类,需要指定(类加载器,被类加载器加载主题类,以及主题类需要实现的接口)
- 通过Proxy类中的newProxyInstance获得代理类的实例,需要指定(类加载器,被类加载器加载的主题类,以及主题类需要实现的接口,InvocationHandler :负责处理方法调用请求)
- 注意:拿到的代理对象实例,如果没有InvocationHandler 是无法调用代理实例对象内部方法。
- 注意:InvocationHandler 接口需要实现invoke()方法。
(4)当目录中存在两个同名主题类
- springboot jar包方式运行时,加载类时是按照maven中的依赖顺序进行加载的,如果已经加载过某个类,则后依赖的jar包中有全限定类名相同的类时是不会被加载到的。
- tomcat中,加载类的顺序是按照jar包在操作系统中的文件排序进行的(这里的文件排序不确定一定是文件名,不同操作系统文件排序规则可能不一样),在多个jar包中有全限定类名相同的类的情况下,jar文件排序靠前的会被优先加载到。