Почему перечисления Java не являются клонируемыми?

В calc, F5 , F6 , F7 , цикле F8 между Шестнадцатеричным числом, декабрь, октябрь, режим Bin.

7
задан Christian Strempfer 17 August 2015 в 18:36
поделиться

6 ответов

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.

6
ответ дан 6 December 2019 в 07:26
поделиться

If your clone method returns this instance rather than a distinct object, then it's not a clone, is it?

The Javadoc says:

By convention, the object returned by this method should be independent of this object (which is being cloned).

Enums are not supposed to be cloned because there is supposed to only ever be one instance of each value.

EDIT: In response to the following comment:

That's exactly what I criticize. Why not return the same instance, if there cannot be a different one?

Because it doesn't really make sense. If it's the same object then it's not a clone. The Javadocs also say:

The general intent is that, for any object x, the expression:

x.clone() != x
will be true, and that the выражение:
 x.clone (). getClass () == x.getClass () 
будет истинным, но эти не являются абсолютными требованиями.

Таким образом, цель состоит в том, чтобы метод clone () возвращал отдельный объект. К сожалению, в нем говорится, что это не абсолютное требование, что делает ваше предложение обоснованным, но я все же думаю, что это неразумно, потому что бесполезно иметь метод клонирования, который возвращает this . Это могло бы даже вызвать проблемы, если бы вы делали что-то сомнительное, например, наличие изменяемого состояния в константах перечисления или их синхронизацию. Поведение такого кода будет различным в зависимости от того, выполнял ли метод clone правильное клонирование или просто возвращал this .

Вы действительно не объясняете, почему вы хотите рассматривать перечисления как Cloneable , когда они по своей сути неклонируемы. Желая иметь метод клонирования, который не

7
ответ дан 6 December 2019 в 07:26
поделиться

I guess they didn't want to treat singletons as a special case when clone() was specified. That would have complicated the specification. So now the library developers have to treat them as a special case, but for the rest of us, it's nice that we can trust that x.clone() != x.

1
ответ дан 6 December 2019 в 07:26
поделиться

Какова цель клонирования синглтона, если x.clone () == x ? Разве вы не можете сразу использовать x .

Строго говоря, если вы хотите что-то клонировать, и применяйте x.clone () == x , единственным объектом, который может быть результатом клона, является сам x :

def clone() {
  return this;
}

Что может вводить в заблуждение ...


Если вы что-то проектируете и основываетесь на clone () для дифференциации, вы неправильно делаете ИМХО ...

9
ответ дан 6 December 2019 в 07:26
поделиться

Your own answer to your question is the best one. In general, people expect clone() to give back a different object. The semantics of Cloneable itself make more sense that way. ("The object is cloneable...oh, I must be able to make copies.") I can't think of a situation offhand where that matters, but that was the intended semantic meaning of Cloneable.

I think that even if they were thinking about singletons, they would not have changed it. After all, it's the programmer's responsibility to decide what can be cloned and what can't, by selectively adding (and potentially overriding) the Cloneable interface, and most programmers are not going to add the Cloneable interface to singletons either.

1
ответ дан 6 December 2019 в 07:26
поделиться

Но для синглтонов, наоборот, я хочу, чтобы x.clone () == x было истинным.

Нет, это не был бы клон. Итак, для синглтонов вам нужно следующее:

public Object clone() throws CloneNotSupportedException {
  throw new CloneNotSupportedException(); 
}
0
ответ дан 6 December 2019 в 07:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: