0

I just stumbled over this question about comparing enum values using == vs. .equals(). The common consent is, that it's absolutely ok to use == as only one enum constant can exist at a time. This was my first thought, too.

But: What about using two (or more) ClassLoaders loading the same class. Not necessarily a enum class. Any class containing static constants.

Imagine the following:

class ContainsConstants {
    public static final Object DEMO_CONSTANT = new Object();
}

Lets reference this value from within another class:

class Pojo {
    public final Object myField = ContainsConstants.DEMO_CONSTANT;
}

Now create two Pojo instances using clazz.newInstance() with clazz being loaded by different ClassLoaders and compare myField to each other and to ContainsConstants.DEMO_CONSTANT:

Thread.currentThread().setContextClassLoader(classLoader1);
Pojo pojo1 = instantiatePojoReflectivelyFromClassLoadedBy(classLoader2);
Pojo pojo2 = instantiatePojoReflectivelyFromClassLoadedBy(classLoader3);
if (pojo1.myField == pojo2.myField) {
    // what happens?
}
if (ContainsConstants.DEMO_CONSTANT == pojo1.myField) {
    // what happens?
}

Question: Will both fields be equal? If not, would an equals method even solve this problem, as it might use static stuff internally (like Strings)?

Community
  • 1
  • 1
Sebastian S
  • 4,420
  • 4
  • 34
  • 63
  • 3
    Well, the best way to know it is to try it. My guess is that it won't work. I have seen things like `A cannot be casted to A` when multiple classloaders loaded the same class, so I would be surprised equality still works on enum since they are basically static attributes of a class (and when static attributes are initialized ? When the class is loaded) – Dici Aug 14 '15 at 22:26
  • That’s an irrelevant question. If `==` fails on singletons or `enum`s due to these being of a different runtime class, their `equals` method will return `false` as well. – Holger Sep 04 '15 at 09:52
  • @Holger the default implementation, yes. But if one is aware of this problem, one might be able to implement around this issue – Sebastian S Sep 04 '15 at 10:11
  • Not really. `Enum.equals` is `final`, so it invariably has the same semantics as a `==` comparison. For other classes you can provide an `equals` method which accepts instances of a different class that happens to have the same name, but it would require Reflection to compare the actual values. It’s also unclear what problem it ought to solve. In your example code, `Pojo` always refers to the same class as it is impossible that a symbolic reference inside one class refers to different runtime classes. Attempts to assign them instances of a different runtime class will cause an exception. – Holger Sep 04 '15 at 10:52

0 Answers0