Original address
https://blog.csdn.net/justloveyou_/article/details/61672133
If there is infringement, please contact to delete, thank you!
Summary:
For a member of a class, whether it can be accessed by other classes depends on the modifier of the member; For a class, whether it can be accessed by other classes also depends on the modifier of the class. In Java, there are four types of class member access modifiers: private, none (package access), protected and public. Only package access and public can modify a class (except internal classes). In particular, many java books give a general introduction to protected visibility. This paper focuses on the visibility connotation of protected keyword and introduces some other modifiers.
1. Package
As for the use of packages, only one thing needs to be noted: in a project, two package names cannot be the same, that is, the package name cannot be the same as other package names in the project. This includes not only the user-defined package name, but also the package name of the class library referenced by the project. Take the following example:
package java.lang; public class MyObject { public static void main(String[] args) throws CloneNotSupportedException { Object o = new Object(); System.out.println(o.hashCode()); } }
The package name we set for our program is Java. Lang. in fact, Java. Lang is the package name used by JDK. At this time, the program can be compiled normally, but when we run the program, there will be a package conflict warning and throw "java.lang.SecurityException: Prohibited package name: java.lang", as shown in the following figure:
In addition, we need to note that in the program, the package statement must be the first program code in the file except the comments, otherwise it cannot be compiled.
2. Overview of Java access rights
For a class, whether its members (including member variables and member methods) can be accessed by other classes depends on the modifier of the member. In Java, there are four access rights modifiers for class members: private, none (package access rights), protected and public. The permission control is shown in the following table:
In particular, different from the access permission category of class members, for Non internal classes, there are only two types of access permission modifiers: public and package access permission (internal classes can be private or protected. For more information about internal classes, please refer to my blog overview of Java internal classes). In particular, if you don't want anyone else to have access to this class, you can specify all constructors as private to prevent anyone from creating objects of this class. At this time, the object of this class can only be created inside its static member. This situation is a bit like the singleton mode, such as the following example:
class Test { // private Constructor! private Test() {} // Allow creation via static method: public static Test getTest() { return new Test(); } }
Among the four modifiers mentioned above, except protected, they are easy to understand and master, and are briefly described here:
- Public: class members modified by public can be accessed directly by all classes;
- Private: a class member modified by private can only be accessed in the class that defines it, and no other class can access it. In particular, we generally recommend setting the member variable to private and providing getters / setters for the outside world to access the member variable, which fully reflects the encapsulation idea of Java;
- Package access permission: package access permission is the default permission in Java. Class members with package access permission can only be accessed by classes in the same package.
- Because the visibility connotation of protected keyword is not easy to understand, we will introduce it in the next section.
3. The real connotation of protected keyword
Many books introducing the Java language (including Java programming ideas) introduce protected in a simple way, basically in one sentence, that is, the members modified by protected are visible to the package and its subclasses. This statement is a little too vague and often misunderstood. In fact, the visibility of protected lies in two points:
- The protected members of the base class are visible within the package and are visible to subclasses;
- If the subclass and the base class are not in the same package, in the subclass, the subclass instance can access the protected method inherited from the base class, but not the protected method of the base class instance.
We can further master the protected keyword through the following examples about the visibility of the protected method. When encountering a call involving a protected member, first determine where the protected member comes from and what its visibility range is, and then judge whether the current usage is feasible. See the following seven examples:
Example 1
//Example 1 package p1; public class Father1 { protected void f() {} // protected method in parent class Father1 } package p1; public class Son1 extends Father1 {} package p11; public class Son11 extends Father1{} package p1; public class Test1 { public static void main(String[] args) { Son1 son1 = new Son1(); son1.f(); // Compile OK ----(1) son1.clone(); // Compile Error ----(2) Son11 son = new Son11(); son11.f(); // Compile OK ----(3) son11.clone(); // Compile Error ----(4) } }
For the example above
First look at (1) (3). The f() method inherits from the class Father1, and its visibility is package p1 and its subclasses Son1 and Son11. Since the package of the class Test1 calling the f() method is also p1, it is compiled at (1) (3).
Next, look at (2) (4). The visibility of the clone () method is the java.lang package and all its subclasses. For the statements "son1.clone();" and "son11.clone();", their clone () is visible in the classes Son1 and Son11, but invisible to Test1. Therefore, the compilation at (2) (4) fails.
Example 2
//Example 2 package p2; class MyObject2 { protected Object clone() throws CloneNotSupportedException{ return super.clone(); } } package p22; public class Test2 extends MyObject2 { public static void main(String args[]) { MyObject2 obj = new MyObject2(); obj.clone(); // Compile Error ----(1) Test2 tobj = new Test2(); tobj.clone(); // Complie OK ----(2) } }
For (1), the clone() method comes from the class MyObject2 itself, so its visibility is a subclass of package p2 and MyObject2. Although Test2 is a subclass of MyObject2, the protected method clone() of the base class MyObject2 cannot be accessed in Test2, so the compilation fails;
For (2), Test2 accesses the clone() of its own instance inherited from the base class MyObject2, so the compilation passes.
Example 3
//Example 3 package p3; class MyObject3 extends Test3 { } package p33; public class Test3 { public static void main(String args[]) { MyObject3 obj = new MyObject3(); obj.clone(); // Compile OK ------(1) } }
For (1), the clone() method comes from the class Test3, so its visibility is packet P33 and its subclass MyObject3, and (1) it is invoked in class Test3 of p33, belonging to the same package, compiled and passed.
Example 4
//Example 4 package p4; class MyObject4 extends Test4 { protected Object clone() throws CloneNotSupportedException { return super.clone(); } } package p44; public class Test4 { public static void main(String args[]) { MyObject4 obj = new MyObject4(); obj.clone(); // Compile Error -----(1) } }
For (1), the clone() method comes from class MyObject4, so its visibility is package P4 and its subclasses (there are no subclasses here), while class Test4 is in package p44, so it does not meet the visibility and fails to compile.
Example 5
//Example 5 package p5; class MyObject5 { protected Object clone() throws CloneNotSupportedException{ return super.clone(); } } public class Test5 { public static void main(String[] args) throws CloneNotSupportedException { MyObject5 obj = new MyObject5(); obj.clone(); // Compile OK ----(1) } }
For (1), the clone() method comes from class MyObject5, so its visibility is package p5 and its subclasses (there are no subclasses here), and class Test5 is also in package p5, so it meets the visibility and passes the compilation.
Example 6
//Example 6 package p6; class MyObject6 extends Test6{} public class Test6 { public static void main(String[] args) { MyObject6 obj = new MyObject6(); obj.clone(); // Compile OK -------(1) } }
For (1), the clone() method comes from class Test6, so its visibility is package p6 and its subclass MyObject6, and class Test6 is also in package p6, so it meets the visibility and is compiled.
Example 7
//Example 7 package p7; class MyObject7 extends Test7 { public static void main(String[] args) { Test7 test = new Test7(); test.clone(); // Compile Error ----- (1) } } public class Test7 { }
For (1), the clone() method comes from the class Object, so the visibility of the clone() method is the package java.lang and its subclass Test7. Because the class MyObject7 is not within this range, it does not meet the visibility and does not pass the compilation
4. Other modifiers
Static: modify variables and internal classes (regular classes cannot be modified). The modified variables are called class variables or static variables. Static variables are and class level variables. Each instance shares this static variable and is initialized when the class is loaded.
Final: the variable declared as final must be given an initial value at the time of declaration (of course, blank final can be delayed to the constructor for assignment), and the modified variable cannot modify the value. When modifying a class, the class cannot derive subclasses; When decorating a method, the method cannot be overridden by subclasses. If readers want to have a deeper understanding of the final keyword, please move to my blog post Java inheritance, polymorphism and class reuse.
Abstract: modifies classes and methods. When decorating a class, the class cannot create an object; When decorating a method, it is an abstract method. As long as a class has an abstract method, the class must be defined as abstract, but the abstract class does not have to have an abstract method.
5. Summary
Protected is one of the most difficult to understand Java class member access modifiers. In programming, when encountering calls involving protected, first determine where the protected member comes from and what its visibility range is, and then use it correctly.