| d2r diego's weblog |
protected does what?Okay, quick, what's the effect of adding the protected qualifier to a class variable in Java? If you're like me (and many others) you'd say: "protected allows only subclasses to access the variable". Wrong! At least according to Java 1.4 and Java 5... We discovered this a few months back while chatting with Erik and I forgot to blog about it. Today I remembered it in a conversation with Martin. Let's look at the Java Language Spec section for protected access, 6.6.2.1 "Access to a protected Member", it states: "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."Hm. That sounds like only subclasses should be able to access it, doesn't it. But try this code. Create package "x". Then create two classes in there, test1 and test2, with the following contents: test1.java test2.javaNot only that will compile, but also running java x.test2 will print "HELLO". Which means that protected is giving package-wide access, not just subclass access. If you read the first definition in the spec:A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.It seems to be loose in specifying only access-denied for non-package classes that do not inherit (a "negative right"), rather than only for inheriting classes (a "positive right", or is it the other way around? nevermind). Okay, so what do you think? Does the Java Lang Spec contradict itself by not spec'ing out completely access in the first paragraph? Or is section 6.6.2.1 enough to say that this is a bug? (And I have confirmed this behavior in JDK 1.4.x and Java 5 as well). Update: Juha, in the comments, notes that section 6.6.1 (a little before the section I referenced) makes the package-distinction clear. Martin agrees. Me? I agree that putting sections 6.6.1 together with 6.6.2 gives us the behavior we're seeing. I might be wrong in reading the text like I am (eu mentioned that in the comments), but I can't quite see it that way. I still think that Section 6.6.2 reads as if it's an all-inclusive rule, particularly since it doesn't reference section 6.6.1, only two paragraphs above, and thus sec. 6.6.2 appears to contradict both the spec from Section 6.6.1 and language behavior. In any case, there's no mystery. At most, I'd say that section 6.6.2 has to be clarified to avoid appearing to contradict 6.6.1. Or rather, the whole section might be rewritten for clarity... Or, I should change the grammar/parser in my head and read the spec differently (admit it, that's what you think we really needed, don't you!). Then all problems would be solved. I'll see if I can call the factory and get an upgrade or something. :-) Categories: soft.devPosted by diego on January 29 2005 at 7:57 PM | TrackBack (1) Comments (please see the comments & trackback policy).
Well, section 6.6.1 of JLS also states "Access to the member or constructor occurs from within the package containing the class in which the protected member or constructor is declared." So I think there's no bug in JLS: it's just somewhat obscure. For what it's worth, there was a "private protected" modifier with semantics similar to C++'s protected (allow access only for subclasses, but not for classes in package) in Java 1.0. It was removed in 1.1 since it was quite useless. Juha, I think that section 6.6.2.1 which says "Access is permitted **only** within the body of a subclass S of C" (my emphasis) contradicts that. Something's wrong somewhere. And I forgot to mention private protected, which I remember created quite a bit of confusion back then, thanks for the reminder. Posted by: Diego at January 29, 2005 10:02 PMDiego, Juha is right. You can't read the spec starting from the end. It is clear and logical enough that section 6.6.1 is saying that protected is visible inside package and also as described in 6.6.2. Posted by: eu at January 29, 2005 11:11 PMSeems like a feature, not a bug, to me. This has been the advertised behaviour of protected ever since I learned Java, though I'll admit to never having read the language spec. I think this is supposed to in analog with the C++ protected qualifier, in that both sub- AND friend classes can access the members. Posted by: cdavies at January 30, 2005 8:09 PMAnd now, to make it a bit more confusing, add a mix of static and instance methods to the brew (check out http://www-106.ibm.com/developerworks/forums/dw_thread.jsp?message=3171433&cat=10&thread=47881&forum=181) Some of the comments indicate that you need to access protected stuff on a base-class (in another package) from inside an instance method of the sub-class. Indeed that always works. But I couldn't find any reference to this limitation in the language specification at the time. And your example using main() is indeed a typical case where the story gets even more complex... Haven't checked 1.5 yet though.. cheers erwin Post a comment
Copyright © Diego Doval 2002-2007.
|
