Why are Java enums not clonable?
clone, enums, java
Solution
But for singletons on the contrary I want `x.clone() == x` to be true.
You may want to, but I think it's weird that the following code would break:
interface Foo extends Cloneable { public int getX(); public void setX(int x); }
enum FooSingleton implements Foo {
INSTANCE;
private int x;
public int getX(){ return x; }
public void setX(int x){ this.x = x; }
}
class FooClass implements Foo {
private int x;
public int getX(){ return x; }
public void setX(int x){ this.x = x; }
}
boolean omg(Foo f){
Foo c = f.clone();
c.setX(c.getX() + 1);
return c.getX() != f.getX();
}
assert omg(new FooClass()); // OK
assert omg(FooSingleton.INSTANCE); // WTF?
(Of course, since `clone()` only gives shallow copies, even a correct implementation of it may cause errors in the above code.)
On the other hand, I can sort of agree that it would make sense for cloning operations to just `return this` for immutable objects, and enums really should be immutable. Now, when the contract for `clone()` was written, they apparently didn't think about immutables, or they didn't want a special case for a concept that's not supported by the language (i.e., immutable types).
And so, `clone()` is what it is, and you can't very well go and change something that's been around since Java 1.0. I'm quite certain that somewhere out there, there is code that totally relies on `clone()` returning a new, distinct object, perhaps as a key for an `IdentityHashMap` or something.
Problem
It's too late to change the question, but more precise would have been to ask "Why does clone() not allow singletons?". A `copy()` method would be more convenient. Is there any reason why enums in Java cannot be cloned? The manual states that This guarantees that enums are never cloned, which is necessary to preserve their "singleton" status. But returning the instance itself would also preserve its status, and I would be able to handle associated enums the same way as other clonable objects. One may argue that The general intent [of clone()] is that, for any object x, the expression: `x.clone() != x` will be true, [...] But for singletons on the contrary I want `x.clone() == x` to be true. If the instance itself would be returned, then the singleton pattern would be transparent to referencing objects. So why are enums not allowed to be cloned or did they forget to think about singletons and immutables, when `clone()` was specified?