úterý 19. srpna 2008

Kdy je Enum roven

Když jsem včera prolétnul článek Neater Java, ve kterém je ukázána zajimává prace s Enum konstruktem/typem, tak mě překvapilo, že se pro porovnání dvou instancí enum používá equals metoda a přemýšlel jsem jestli není možné použít přímo test identity ==, když se vlastně jedná o konstantu.

Moje pátrání začalo v metodě Enum#equals(java.lang.Object), která je finální a její obsah je poměrně všeříkající.

public final boolean equals(Object other) { 
    return this==other;
}
        

Sice jsem byl spokojen, že na tato implementaci Enumu můžu použít test identity, nicméně se mi to zdálo vachrlaté přeci jenom jsem se nechtěl spolehát na implementační detail a hledal jsem nějaký exaktní důkaz a nakonec jsem našel na místě nejpovolanějším a to přímo v Java Language Specification, kde v sekci 8.9 Enums.

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant. (The equals method in Enum is a final method that merely invokes super.equals on its argument and returns the result, thus performing an identity comparison.)

Každopádně pokud používáte RMI a to i nepřímo například skrze vzdálené volání EJB, tak máte s enum typy problém, protože serializace RMI-IIOP (klasická Java serialziace funguje korektně) s nimi jaksi nepočítá viz defekt Serialization of Enums over IIOP is broke.