在Threads之间传递对象时是否可以使用instanceof?

我遇到了一个问题,其中instanceof工作,然后它没有。 进入细节很困难,但我认为这可能是问题所在:

阅读本文: http : //www.theserverside.com/news/thread.tss? thread_id = 40229(搜索Thread.currentThread),似乎暗示即使两个对象是同一个类,如果你传递它们在具有不同类加载器的线程之间,instanceof(和isAssignableFrom)可能仍会失败。

这当然可以解释我的行为,但我想知道是否有人可以validation它?

(我希望在讨论开始时链接的文章仍然可用,但它似乎不是。)

这与线程无关,只与类加载器有关。 当由不同的类加载器加载时,相同的类定义被JVM视为两个不同的类。 因此,两者之间的instanceof或演员都失败了。

所以回答你原来的问题: 在同一个类加载器加载的线程之间传递对象是安全的,而instanceof等。 工作良好。

这是一篇关于类加载问题的文章 。

另请参阅我之前的回答,以了解validation游戏中哪些类加载器的方法。

更新Romain的评论

以下是一些测试instanceof行为的代码,其中包括:

 URL[] urls = new URL[] {new File("build/classes/").toURL()}; ClassLoader loader1 = new URLClassLoader(urls, null); ClassLoader loader2 = new URLClassLoader(urls, null); Class c1 = loader1.loadClass("net.torokpeter.Foo"); Class c2 = loader2.loadClass("net.torokpeter.Foo"); Object foo1 = c1.newInstance(); Object foo2 = c2.newInstance(); System.out.println("c1.toString(): " + c1); System.out.println("c2.toString(): " + c2); System.out.println("c1.equals(c2): " + c1.equals(c2)); System.out.println("c1 == c2: " + (c1 == c2)); System.out.println("foo1: " + foo1); System.out.println("foo2: " + foo2); System.out.println("foo1 instanceof Foo: " + (foo1 instanceof Foo)); System.out.println("foo2 instanceof Foo: " + (foo2 instanceof Foo)); System.out.println("c1.isAssignableFrom(c1): " + c1.isAssignableFrom(c1)); System.out.println("c2.isAssignableFrom(c2): " + c2.isAssignableFrom(c2)); System.out.println("c1.isAssignableFrom(c2): " + c1.isAssignableFrom(c2)); System.out.println("c2.isAssignableFrom(c1): " + c2.isAssignableFrom(c1)); System.out.println("c1.isAssignableFrom(Foo.class): " + c1.isAssignableFrom(Foo.class)); System.out.println("c2.isAssignableFrom(Foo.class): " + c2.isAssignableFrom(Foo.class)); System.out.println("Foo.class.isAssignableFrom(c1): " + Foo.class.isAssignableFrom(c1)); System.out.println("Foo.class.isAssignableFrom(c2): " + Foo.class.isAssignableFrom(c2)); 

输出是(在Eclipse中,Java5):

 c1.toString(): class net.torokpeter.Foo c2.toString(): class net.torokpeter.Foo c1.equals(c2): false c1 == c2: false foo1: net.torokpeter.Foo@360be0 foo2: net.torokpeter.Foo@45a877 foo1 instanceof Foo: false foo2 instanceof Foo: false c1.isAssignableFrom(c1): true c2.isAssignableFrom(c2): true c1.isAssignableFrom(c2): false c2.isAssignableFrom(c1): false c1.isAssignableFrom(Foo.class): false c2.isAssignableFrom(Foo.class): false Foo.class.isAssignableFrom(c1): false Foo.class.isAssignableFrom(c2): false 

所以一切似乎都是一致的:-)

问题就像PéterTörök所说的那样,有了类加载器。 从本质上讲,这也是JNDI的原因,它允许通过单个中央类加载器创建公共对象(也意味着您需要的类需要位于单个中央类加载器的类路径中,当您使用时可以提供各种乐趣需要的不仅仅是字符串)。