最近在面试中遇到一道问题,把我问得有点蒙蔽。这个问题是这样的,现在有一个WAR包,我们定义了一个类A,然后这个WAR包引用了一个JAR包,也有一个类A,两个类A全限定名相同,那么虚拟机会加载哪一个类呢?
OK,遇到这个问题的第一感觉,在Java项目中能够存在两个相同的全类名的类吗,结果在线下实现了一下,确实可以。
我自己通过maven打了一个jar包。全限定名为test.lang.Person。然后项目引用了这个jar包。
在引用的jar包中类的静态代码块儿中写了 init from jar.
然后又在项目中定义了一个java.lang.Person。同时在类中的静态代码块儿中也写了一行代码 init from project
然后运行代码。
public class Main {
public static void main(String[] args) {
Person person = new Person();
Class cls = person.getClass();
ClassLoader classLoader = cls.getClassLoader();
System.out.println(classLoader);
}
}
结果出来是,是加载的在项目中定义的类A。
随后我将项目中的类A去掉, 只保留jar包中的类A,结果可想而知。虚拟机是从jar包中加载的类A
那么为什么会这样呢?其实这个问题,我们可以直接进入ClassLoader的代码找到答案。上面可以看到,实际加载这个类的类加载器就是AppClassL