0

I learnt that Object.clone() and Cloneable have some bad design decisions. However I have some more doubts:

  1. Why Object.clone() has protected modifier, while others like Object.toString(), Object.equals() are not protected? Why to make clone() inaccessible to non subclasses from different packages and not to keep them public like toString() and equals()?

  2. This page says:

    Object clone is a protected method, so we will have to override it to use with other classes.

    I feel above fact is plain wrong as protected modifier does not impose any such restriction. We can still call clone(), but it will throw run time exception, but not compile time exception.

  3. How every class in Java is sub class of Object class? Most likely answer is "by design". But I wanted to know where this fact is enforced? Usually to extend a class, we use extends keyword. But we dont make every custom class do extends Object. Then where does it happen? Does compiler auto generates bytecode by enforcing such restriction?
MsA
  • 2,599
  • 3
  • 22
  • 47
  • #2 answers #1, you just don't believe it (try calling `clone()` on an object from a class that's from a different package and the compiler will stop you). #3 is simple: the compiler enforces it. It treats `class Foo {` as if you'd have written `class Foo extends java.lang.Object {`. – Joachim Sauer Mar 20 '20 at 12:28
  • @Sam [this comment](https://stackoverflow.com/questions/60745648/why-does-cloneable-not-have-clone#comment107475848_60745648) and also [this answer](https://stackoverflow.com/a/26415589/6357916) – MsA Mar 20 '20 at 12:29
  • @JoachimSauer I just created a custom class in some custom package and in its main method created its instance and then called `clone()` on that instance, it threw `CloneNotSupportedException`. So code was getting compiled, but was failing at runtime. Point is if every class extends Object, then *whats the point in having `protected` modifier on `clone()`? Isnt it same as `public`?* – MsA Mar 20 '20 at 12:39
  • 1
    you're calling `clone` from within the same package, which `protected` will allow. You need two packages two test this, one with the class that you want to call `clone` on and another one with the class that *calls* `clone`. – Joachim Sauer Mar 20 '20 at 12:40
  • What would be the point of `protected` being equivalent to `public`? Besides, we know that they're not equivalent. – Kayaman Mar 20 '20 at 12:51
  • Let's say you create a `anir.car.Dash` which has a super sweet `anir.car.Radio`. You want the entire world to know that `anir.car.Dash.toString()` is `Dash with RadioXXX`, no matter what. But you also know that `anir.car.Dash.clone()` does a shallow copy and the associated `Radio` is not cloned. `dash1.getRadio() == dash2.getRadio()`. Therefore, in order for `ken.car.CarFactory` to clone your dash, it would not be correct, I'd only have 1 Radio. In this way YOU as the designer of `anir.car.Dash` needs to implement a public version that calls `Dash.clone()` then `Radio.clone()` for me. – kendavidson Mar 20 '20 at 12:56
  • I understood my 2nd question is wrong. But now the doubt is why to make `clone()` inaccessible to non subclasses from different packages and not to keep them public time `toString()`, `equal()`? – MsA Mar 20 '20 at 13:03
  • I made some mistakes. Now I modified question 1 and 2. – MsA Mar 20 '20 at 13:11
  • @Kayaman my mistake, corrected that. But, why to make `clone()` inaccessible to non subclasses from different packages and not to keep them public like `toString()` and `equals()`? – MsA Mar 20 '20 at 13:35
  • 3
    @anir it's not public because it's usually not implemented. You need to implement it and make it public, then you know it's safe to use. Now that it's protected the compiler can prevent you from trying to clone a class that doesn't implement `Cloneable` (although you could still override `clone()` and not implement `Cloneable`). But it really should've been defined in `Cloneable` interface. Not that it matters, since you shouldn't be using `clone()` anyway. – Kayaman Mar 20 '20 at 13:39
  • @Kayaman Am struggling to get the comment. **(1)** "because it's usually not implemented", you mean by developers are less frequent to implement it? **(2)** "Now that it's `protected` the compiler can prevent you from trying to clone a class that doesn't implement `Cloneable`" - calling `clone()` on non `Cloneable` class does not give compiler time error but gives runtime `CloneNotSupportedException`. (continued..) – MsA Mar 21 '20 at 15:51
  • (..continued) **(3)** "you shouldn't be using clone() anyway" - you mean I should not call it at all? But [doc](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone()) says "the returned object should be obtained by calling super.clone". It means my custom implementation of `clone()` should call `Object.clone()`, something like explained [here](https://www.journaldev.com/60/java-clone-object-cloning-java#java-clone-object-best-practices) – MsA Mar 21 '20 at 15:51
  • 1. Yes 2. Re-read what the `protected` modifier means until you understand it, it seems you still think `public` and `protected` are the same. 3. Yes, you **should not** use `clone()`. Just forget that the whole method exists. – Kayaman Mar 21 '20 at 15:56

0 Answers0