• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Protected methods in Object (clone, finalize) extra-protective

 
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My confusion arose from a discussion in this thread. I've read quite a few links (see below), notably c2.com and the JLS (20.1) and found no answer. I hope it's hidden somewhere in the JLS and I'm just not finding it. I'm using JDK 1.5.0_01b.

Here's a summary of the issue.
  • public class A
  • public class B extends A
  • B's methods can call A's protected methods on A references, as expected.
  • B's methods can call Object's protected methods on B references, as expected.
  • B's methods cannot call Object's protected methods on A references. (compile error: "foo() has protected access in java.lang.Object")

  • Unless I've made some other mistake, the protected methods in Object are "extra protective." How is this so? If there's some magic compiler trickery, shouldn't the JLS mention it? BTW, static and instance methods have the same results.

    As a further test I put in another level in inheritence (class C extends B) and added a protected method to A itself. Yet C's methods can call A's protected method on A references but still not Object's protected methods.

    Note that I'm speaking of calling methods on A references -- not on the "this" object. The latter case works fine.

    Here are the three classes to see for yourself.Here are some of the links I've checked:
  • Cloneable Does Not Implement Clone -- Portland Pattern Repository
  • Controlling Cloneability -- Thinking in Java
  • Java Language Specification about Object.clone()
  • Bugs 4403947 and 5045376 -- Sun's Bug Parade


  • [ January 30, 2005: Message edited by: David Harkness ]
     
    author and iconoclast
    Posts: 24207
    46
    Mac OS X Eclipse IDE Chrome
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Object seems different from your other classes only because it's in a different package from A, B, and C. Remember that a group of classes can access each other's protected methods regardless of any inheritance relationships if they're all in the same package.

    The rule for protected method access is a little bit odd when you first hear it. The JLS explains it here.

    Imagine that your classes A, B, and C are in three separate packages, and A defines a protected member foo(), B subclasses A, and C subclasses B. The rule is that B is allowed to call foo() only on instances of B or C and not on instances of A. This is stated in JLS 6.6.2.1:


    Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:

    * If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
    * If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.



    In your scenario, then, you should now be able to understand why B can call clone() on instances of B(), but not on instances of A. B can call A's protected method copy() on instances of A only because B and A are in the same package; if you moved A and B to separate packages, B's ability to do this would go away.

    I hope this clears things up for you!
     
    David Harkness
    Ranch Hand
    Posts: 1646
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thank you! Yes, that absolutely answers my question. Indeed, I separated all three classes, and it behaves as you stated.The funny thing is that I was actually surprised that I could call protected methods through the references, that I am aware of the strangeness of protected with regard to packages, and yet I didn't connect the two. Admittedly, whenever the package/protected dichotomy comes up, I always need to look it up to get the exact rules straight. Maybe this will make it stick in my brain.

    Thanks again. "Up" is now "up" in my world again.
     
    Consider Paul's rocket mass heater.
    reply
      Bookmark Topic Watch Topic
    • New Topic