Does static modifier change the access level of a class member in java?
Asked Answered
R

2

6

I am reading the book of OCA & OCP for java 7 certification and I am trying the exercises of the book with java 8 and I noticed something wired.

I have Class1 class as follows:

package cert;
public class Class1{
    protected static void importantMethod(){
    System.out.println("importantMethod() method of Class1 class TEST \n");
}

The modifiers of importantMethod() method are protected static and the package is cert as you may see, and as explained in the book I would expect that another class from another package, in my case Class2 shown bellow, can access the importantMethod() method only through inheritance, but it turned out that from Class2 I could access the importantMethod() method through an instance of Class1 as well.

Class2 class:

package exam;
import cert.Class1;
class Class2 extends Class1 {
    public static void main(String[] args) {
        Class1 c1 = new Class1();
        c1.importantMethod();
    }
}

If I remove the static modifier from Class1 it gives the expected error when trying to access the importantMethod() method from the Class2:

exam\Class2.java:7: error: importantMethod() has protected access in Class1
            c1.importantMethod();
              ^

My question is, does a non access modifier change the level of access for a member of a class?

Reverse answered 11/4, 2017 at 13:3 Comment(7)
"The modifiers of Class1 are protected static"... Your question clearly shows it as publicPositive
@cricket_007 he should've meant the modifiers of the method 'importantMethod'.Gainful
Related: #24289570Positive
Static members are properties of the class and non-static members are properties of the object or instance. The quick answer is no, static doesn't change the level of access, but the type of access.Pentastich
Hi @DrewKennedy, so it is wired that I could access the importantMethod through an instance of Class1 and not as an inherited member right?Reverse
@Arber You never used it as an inherited member. You made a new Class1, not a Class2Positive
Compiler should have stopped me to use it other than an inherited member, that is my point, why did I not get an error when I did not call the importantMethod as an inherited member?Reverse
H
3

Everything is fine - that's how protected access is meant to work. It's specified in JLS 6.6.2.1:

Let C be the class in which a protected member 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:

  • [Irrelevant stuff as Id does not denote an instance field or instance method]

Your code is within the body of a subclass S of C (where S is Class2 and C is Class1) so it's fine.

Hertahertberg answered 11/4, 2017 at 14:5 Comment(9)
Hi @JonSkeet, this part of the book made me confuse: This makes the variable accessible to all other classes inside the certification package, as well as ** inheritable by any subclasses outside the package** . Finally, we've seen that subclasses outside the package can't use a superclass reference to access a protected member. For a subclass outside the package, the protected member can beaccessed only through inheritance. Thank you for your answer.Reverse
@ArberHoxha: Well that's just a not-terribly-clear way of saying the same thing. The "only through inheritance" is being used as a shorthand for the "only within the body of a subclass S of C" and the parts that follow.Hertahertberg
Please take a look at the example between page 38 and 39 at this picture: dropbox.com/s/4gdl6ry939285gi/Protected.PNG?dl=0Reverse
@ArberHoxha: Yes, and that's explained by the rules that are in the "irrelevant stuff" because that's showing an instance field. Your question shows a static field. Really, just read the section of the spec that I referred you to.Hertahertberg
@ArberHoxha I think maybe additionally where you are confused is that the main method is not inheritedPositive
Sorry @cricket_007 I did not understand you, what do you mean by "main method is not inherited"?Reverse
@ArberHoxha I mean exactly that... Class2 extends Class1 has a public static void main method. It is not "inherited from Class1" (assuming you had a main method there). You called a protected method on a Class1 instance in a separate package and not using a Class2 instance.Positive
@cricket_007 what you are saying does not answer my question that I did in the beginning I think: "My question is, does a non access modifier change the level of access for a member of a class?" Maybe I am becoming too stubborn here but I am not being able to understand if here is being broken the access control that protected forces or not. If you are sure that you have given the answer to me I withdraw and will try to analyse better the answers that you have given to me. Thanks a lot :)Reverse
@ArberHoxha: No, the compiler is behaving correctly, according to the language specification. The book you're using just used unfortunately oversimplistic terminology.Hertahertberg
P
2

it turned out that from Class2 I could access the importantMethod() method through an instance of Class1

You don't need an instance to call a static method. Class1.importantMethod() works fine. If you remove static, it doesn't, and that's what you're seeing.

If I remove the static modifier from Class1 it gives the expected error

Because you're in a different package and not calling the method through inheritance like so

package exam;
import cert.Class1;
public class Class2 extends Class1 {

    public static void main(String[] args) {
        new Class2().importantMethod();
    }
}
Positive answered 11/4, 2017 at 13:17 Comment(10)
Hi @cricket_007, you said You don't need an instance to call a static method. That's why that worked., but it should not work, because I am still in a different package and the importantMethod() method has protected access modifier, that is why I am asking why it worked. It is protected anyway, it shouldn't matter if it static or not I think, because static is a non access modifier right? Anyway I can not call theReverse
c1.importantMethod() is not correct when it's a static method. Class1.importantMethod() is how you refer to a static method and protected doesn't affect that, I don't thinkPositive
But c1.importantMethod() worked. If that was not correct shouldn't I have taken an error in that case?Reverse
It's a compiler warning. It's syntactically incorrect. You never need an instance to call a static method. That's my only pointPositive
Ok, maybe is a problem of the compiler that did not "protect" the importantMethod from being called from another class in another package not as an inherited member even though importantMethod had the protected access modifier...Reverse
Static members are tied to classes, not instances so there can only be one copy of any static member and importantMethod is a static member of Class1.. Btw, protected access is not the same as private access which may be where you are getting confused Arber.Panada
Hi @NickSimpson, I was more focused on the access level reather than on the way that importantMethod is accessed.Reverse
I edited my comment, maybe have another quick read up on the differences between private and protected access.. Protected is almost the same as default access.Panada
I know the difference between private and protected because I am reading the book of OCA & OCP and according to the book, protected allows the access of a member of class by other classes in the same package as the default access level and it allows that the classes from another package can access the member of a class ONLY through the inheritance right? This is the problem, in my case I do not access the importantMethod as an inherited member but through an instance, according to the rules of protected explained above that should NOT happen. Am I missing something else?Reverse
No, you are not accessing it through an instance, there is only one copy of it as it is a static member, you need to go back and read your study material again as you haven't understood it properly.Panada

© 2022 - 2024 — McMap. All rights reserved.