To the best of our knowledge, foo == bar will always evaluate to true, assuming both foo and bar were assigned using equivalent constant string expressions, or using the intern() method on an equivalent string. Even if they're from different classes, classloaders, whatever. The JVM has exactly one string intern pool, outside any classloader, and it retains at most one instance of any given string content.
The only known exception is achieved by reformulating the question a bit and comparing two interned strings which are not in the JVM
at the same time. That is, it's possible to load a string into the intern pool, then cause it to be unloaded, then intern another string with the same content, and determine that the new string is different than the original, using System.identityHashCode().
To do this with string constants, this requires you to use one classloader to load a class containing the constant, then make the class and classloader eligible for GC, then hope that GC successfully removes the classloader, class, and interned string, then use a new classloader to load a class with an equivalent constant. This may sound like a rare occurrance, but it can happen quite easily in an environment like a web app server. However since the two interned strings cannot be in the JVM at the same time (else the intern pool would resolve them to a single instance), it's impossible to compare them directly usign either == or equals(), or compareTo() or most other tests that might detect that the instances are different. Accordingly, this doesn't actually affect people very often; it's somewhat similar to debating how many angels can stand on the head of a pin.