通过多个类加载器获得的类实例

时间:2011-03-21 08:36:20

标签: java classloader

我正在阅读this文章,它说:

  

如果我们有两个由这些CustomClassLoader加载的Student类实例,例如student1和student2,那么student1和student2不是类型兼容的。换句话说,

     

学生3 =(学生)学生2;

     

将抛出ClassCastException,因为JVM将这两者视为独立的不同类类型,因为它们由不同的ClassLoader实例定义。

现在我明白了它想传达的内容:那就是如果我们通过使用两个不同的类加载器来加载相同的类,那么它们将不是类型兼容的。所以很好。

但它使用的例子让我感到困惑,即

  

学生3 =(学生)学生2;

当我们声明像 Student student 这样的引用变量时,编译器所寻找的是 Studnet 存在的所有内容在运行时,我们将这个引用变量分配给一个真正的加载类,我们用哪个类加载器加载所述类真的很重要吗?我怀疑,因为根据我的理解,只有当我们执行'new'或者我们在其上调用静态字段时才会使用类加载器,而不是在我们简单地声明它的类型时。

请在此澄清我,并帮助我纠正我在这方面的理解。

谢谢, Mawia

2 个答案:

答案 0 :(得分:3)

这大多是正确的但是当分配发生时,JVM需要确保它是正确的。因此它检查:我可以将右侧(RHS)分配到左侧(LHS)。

规则说当你可以将RHS的运行时类型向下转换为LHS的类型时允许这样做。

所以在编译时,上面的代码看起来没问题。但是在运行时,调用isAssignableFrom()返回false,因为这两种类型不同。

equals()中的方法Class返回true,如果限定名称等于,>当类加载器相同时。这就是为什么你在这种情况下获得ClassCastException

使用的方法是作为本机代码实现的,因此您无法看到正在发生的事情。但是,当两个类的类加载器相同时,方法isInstance()isAssignableFrom()仅返回true。

答案 1 :(得分:1)

是的,在运行时,哪个类加载器确实加载了一个类真的很重要。每次必须加载类时都会检查类加载器。这不仅仅是遇到new或静态字段时。每次在Java代码中出现类名时都会发生这种情况,或者更确切地说,在字节代码中引用类名并执行字节代码时会发生这种情况。