The keyword protected
grants access to classes in the same package and subclasses (http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html).
Now, every class has java.lang.Object
as superclass (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html).
Hence I conclude that every class may access java.lang.Object
's methods even if they are protected
.
Take a look at the following example:
public class Testclass { public Object getOne() throws CloneNotSupportedException { return this.clone(); } public Object getTwo() throws CloneNotSupportedException { return ((Object) this).clone(); } }
While getOne()
compiles fine, getTwo()
gives
Testclass.java:6: clone() has protected access in java.lang.Object return ((Object) this).clone();
I neither understand why getTwo()
doesn't compile nor what's the difference (regarding the access of java.lang.Object
s members) with getOne()
.
When you said "
((Object) this).clone()
", you accessed your own object via its superclass Object. You performed a widening conversion to an Object. The code then attempts to call clone on Object.But, as you've noted, clone is a protected method, meaning that only if your object was in the same package of java.lang would it be able to access the OBJECT's clone method.
When you say this.clone, your class extended Object and thus had access to override or use clone directly through the protected class modifier because of inheritance. But that doesn't change the Object implementation.
By saying ((Object) yourObject), you get something that is only accessible through the Object class. Only public methods of the Object class are accessible ouside of the package java.lang, so you get the compile-time exception, because the compiler knows this.
By saying this.clone(), you are invoking your object's clone method that it got through inheriting through Object, and is now able to be invoked because it becomes a part of your custom subclass.
The difference is how you are accessing Object.clone(). clone is only accessible when accessed via a sub class or class in the same package. In the getOne() example you are claling this.clone(). This clearly satisfies access from within a sub class.
In getTwo() though you are acessing Object.clone() and not TestClass.clone(). In order for this to work you must have package level access to Object which you don't and hence the error.
You can only access protected members of a type in a different package if the compile-time type of the expression you're referencing it through is either your own class or a subclass. (Where "your" class is the class containing the code.) Your own class has to be a subclass of the type which originally declares the method, too.
Here's an example; assume that
Base
is in a different package to all the other classes:In other words, it's letting you have access to the protected members of "objects which are a like you".
Details are in section 6.6.2 of the Java Language Specification: