Question

J'ai rencontré un problème qui fonctionne instanceof, et il ne fonctionne pas. Entrer dans les détails est difficile, mais je pense que cela pourrait être le problème:

Lire ceci: http://www.theserverside.com/news/ thread.tss? thread_id = 40229 (recherche Thread.currentThread), il semble impliquer que, même si les deux objets sont de la même classe, si vous les passer entre les fils avec des chargeurs de classe, instanceof (et IsAssignableFrom ) pourrait encore échouer.

Ceci expliquerait le comportement que je vais avoir, mais je me demandais si quelqu'un pouvait le vérifier?

(je souhaite l'article lié au début de la discussion était encore disponible, mais il ne semble pas comme il est.)

Était-ce utile?

La solution

Cela n'a rien à voir avec les discussions, seulement avec des chargeurs de classe. La définition même de la classe, lorsqu'il est chargé par différents classloaders, est considérée comme deux classes différentes par la machine virtuelle Java. Alors instanceof ou moulages entre les deux échouent.

Pour répondre à votre question originale: objets passant entre les fils chargés par la même classe chargeur est sûr et instanceof et al. fonctionne très bien.

Voici un article à propos de problèmes de chargement de classe .

Voir aussi cette réponse plus tôt de la mine un moyen de vérifier quels sont classloaders dans le jeu.

Mise à jour le commentaire de Romain

Voici un code pour tester le comportement de instanceof, entre autres:

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));

Et la sortie est (dans 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

Donc, tout semble cohérent: -)

Autres conseils

Le problème est, comme le dit Péter Török, avec classloaders. Incidentially, c'est aussi la raison pour JNDI qui permet aux objets communs à créer par un classloader central unique, (ce qui signifie aussi que les classes dont vous avez besoin, besoin d'être dans le classpath du classloader central unique, donnant toutes sortes de plaisir lorsque vous besoin de plus cordes).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top