I understand the purpose of making the clone and finalize method as protected, I wanted to understand why hashcode() and equals method are not declared as protected
Because you want to call hashcode and equals methods from the outside of that given class.
protected allows access only from the same package and extending classes.
You "understand the purpose of making the clone and finalize method as protected". But what is the purpose actually?
Calling Object.clone will throw an exception if the method isn't overridden and if Cloneable isn't implemented. Thus this method isn't ready to use.
Object.finalize is according to JavaDoc "called by the garbage collector". Thus it is for internal usage only.
In contrast to these both methods are Object.equals and Object.hashCode ready to use and not for internal usage.
The JavaDoc of Object.hashCode says:
This method is supported for the benefit of hash tables such as those
provided by HashMap.
Thus it is intended to be used by other objects. If hashCode wouldn't be declared public this functionality would be limited usable.
Object.equals is a symmetric method. If Object.equals wouldn't be declared public, suppose we have a local variable b of a type from another package and whose equals method isn't visible to this. We want to ckeck if b and this are equal. We couldn't call b != null && b.equals(this) but we could still call this.equals(b). Does it makes sense to limit a symmetric method to be callable by one of both objects only?
See also Comparable.
What is the specific reason that clone() is defined as protected in java.lang.Object?
The fact that clone is protected is extremely dubious - as is the fact that the clone method is not declared in the Cloneable interface.
It makes the method pretty useless for taking copies of data because you cannot say:
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
I think that the design of Cloneable is now largely regarded as a mistake (citation below). I would normally want to be able to make implementations of an interface Cloneable but not necessarily make the interface Cloneable (similar to the use of Serializable). This cannot be done without reflection:
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Citation From Josh Bloch's Effective Java:
"The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be emulated ... In order for implementing the interface to have any effect on a class, it and all of its superclasses must obey a fairly complex, unenforceable and largely undocumented protocol"
The Clonable interface is just a marker saying the class can support clone. The method is protected because you shouldn't call it on object, you can (and should) override it as public.
From Sun:
In class Object, the clone() method is declared protected. If all you do is implement Cloneable, only subclasses and members of the same package will be able to invoke clone() on the object. To enable any class in any package to access the clone() method, you'll have to override it and declare it public, as is done below. (When you override a method, you can make it less private, but not more private. Here, the protected clone() method in Object is being overridden as a public method.)
clone is protected because it is something that ought to be overridden so that it is specific to the current class. While it would be possible to create a public clone method that would clone any object at all this would not be as good as a method written specifically for the class that needs it.
The Clone method can't be directly used on any object, which is why it is intended to be overriden by the subclass.
Of course it could be public and just throw an appropriate exception when cloning is not possible, but i think that would be misleading.
The way clone is implemented right now makes you think about why you want to use clone, and how you want your object to be cloned.
IMHO it's as simple as this:
#clone must not be called on non-cloneable objects, therefore it is not made public
#clone has to be called by subclasses ob Object that implement Cloneable to get the shallow copy of the right class
What's the right scope for methods that shall be callable by subclasses, but not by other classes?
It's protected.
Classes implementing Cloneable of course will make this method public so it can be called from other classes.
It is protected because the default implementation does a shallow memberwise copy of all fields (including private), circumventing constructor. This is not something an object might be designed to handle in the first place (for example, it might keep track of created object instances in a shared list, or something similar).
For the same reason, the default implementation of clone() will throw if the object it's called on doesn't implement Cloneable. It's a potentially unsafe operation with far-reaching consequences, and therefore author of the class must explicitly opt-in.
From the javadoc of cloneable.
* By convention, classes that implement this interface (cloneable) should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {#link java.lang.Object#clone()} for details on overriding this
* method.
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
So you could call clone on every object but this would give you most of the time not the results you want or an exception. But is only encouraged if you implement cloneable.
Clone() method has a check internally 'instance of Cloneable or not'.This is how Java team might thought will restrict the improper use of clone() method.clone() method is protected i.e. accessed by subclasses only. Since object is the parent class of all sub classes, so Clone() method can be used by all classes infact if we don't have above check of 'instance of Cloneable'. This is the reason Java team might have thought to restrict the improper use of clone() by having the check in the clone() method 'is it instance of Cloneable'.
Hence whatever classes implement cloneable can use clone() method of Object class.
Also since it made protected, it is available to only those sub classes that implements cloneable interface. If we want to make it public, this method has to be overridden by the sub class with their own implementation of it.
Yes, same problem that I met.
But I solve it by implementing this code
public class Side implements Cloneable {
public Side clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
}
return side;
}
}
Just as the before someone said.
Well, also the sun developers are only human, and they did indeed make huge mistake to implement the clone method as protected, the same mistake as they implemented a non-functioning clone method in ArrayList! So, in general, there exist a much deeper misunderstanding of even experienced Java programmers about the clone method.
However, I've recently found a fast and easy solution to copy any object with all its content, no matter how it is built and what it contains, see my answer here: Bug in using Object.clone()
Again, Java JDK framework shows brilliant thinking:
Cloneable interface does not contain a "public T clone();" method because it acts more like an attribute (eg. Serializable) which allows an instance it to be cloned.
There is nothing wrong with this design because:
Object.clone() will not do what you want with your custom-defined class.
If you have Myclass implements Cloneable => you overwrite clone() with
"public MyClass clone()"
If you have MyInterface extends Cloneable and some MyClasses implementing MyInterface:
simply define "public MyInterface clone();" in the interface and every method using MyInterface objects will be able to clone them, no matter their MyClass-class.
If a subclass implements a instance method which has the same signature with its superclass, it is called override.
Comparatively if "override" a static method of its superclass, it is called hiding.
What is the difference between these two concepts in memory during function call ?
Overriding is a run-time phenomenon which depends on object and objects are created at run time so function call will be decided based on object at run time.
Whereas Static method calling is done by adding a class name like
MyClass.abc();
This does not depends on object as you are clearly mentioning the class name at compile time which has nothing to do with object because this static method is global to all object. So whatever class name you will mention that method will be called in case of the static method.
Addresses of static methods are determined at compile time. So there is no need to search further for the method address, it's decided way before.
Overridden method addresses are determined at run time. It depends on the instance and the address of the method is searched from base method to overridden method.
I tried the following code in a main method of a class that I wrote:
public static void main(String[] args){
...
Object s = new Object();
s.finalize();
...
}
However, the eclipse give me a tip that
The method finalize() from the type Object is not visible
I am so confused because the type Object has a protected finalized method, which is supposed to be visible by its own? Am I wrong anyway?
Object#finalize() is a protected method. You can't call it like that. A protected member of a class is inherited by it's direct subclass. You can access it inside that direct subclass on this reference, but not using the reference of that class directly.
It would be like this:
class Demo {
public void test() {
this.finalize();
}
}
BTW, why do you want to invoke it? That method is automatically invoked by JVM to clear any resources that an object is using, just before the object is completely removed from the memory.
finalize() method is called when an object is about to be destroyed.
If you have a custom class, then you can override this method in order to do something.
You shouldn't call this method directly. JVM's garbage collector will do that for you automatically.
And you shouldn't depend on the finalize() method to clear any resources, as it may never happen during the execution of your program.
protected means that you can only access that method if you are in the same package than the Object. And the Object is in package: java.lang.Object your program is in package com.yourpackage.something ==> you cannot access it from your package
I know this question has been asked so many times.
First of all Object.clone() method in java is native method i.e. it is implemented in JVM and user doesn't need to know about it's implementation.
My question is whether this method is abstract too. If not why it has to be overridden in the class that we want to clone.
And one more question .
It is overridden as follows
public Object clone() {
MyClass obj;
try {
obj = (MyClass)super.clone();
} catch(CloneNotSupportedException e) {
Statements
}
return obj;
}
In the 4th line of this code we called , super.clone() method , which clone() method are we calling in this line and if Object.clone() method why did we override it , we can simply cast it wherever we want to clone the Object like
MyClass obj2 = (MyClass)obj1.clone();
and is their any way to know the coding of Object.clone() method?
A method cannot be native and abstract at the same time because native is a statement about a specific implementation of a method;
clone must be overridden at least because Object#clone is protected to prevent access to clients in the case the object does not support cloning;
in many cases clone needs to do more than Object#clone, which just makes a binary copy of the original, which amounts to a shallow clone, with all the referenced objects staying the same;
there's no point in catching CloneNotSupportedException in the subclass: you should already know whether the superclass does or doesn't support cloning (it is not something which can change at runtime).
Object.clone() is not abstract. Overriding it when implementing Clonable is just a convention. (Clonable is a marker interface - like Serializable etc.)
Overriding methods (should) always call Object.clone() directly or indirectly.
I think, casting it is not necessary because Object.clone() preserves the exact class. If you catch the CloneNotSupportedException you could even return MyClass.
As Object.clone() is implemented natively you would have to look at the sources of some JVM implementation like OpenJDK.
My question is whether it's abstract too
No it isn't, and the Javadoc already tells you that, as does the fact that Object itself isn't abstract, and it 'doesn't have to be overridden in the class we want to clone' unless you want to change the access permission, which has nothing to do with 'abstract': and you couldn't call 'super.clone()' in such an override unless it wasn't abstract.
In short, your question doesn't make much sense.