Appearance
Scope
In Java, we often see the public
, protected
, and private
modifiers. In Java, these modifiers can be used to limit access scope.
public
class
and interface
defined as public
can be accessed by any other class:
java
package abc;
public class Hello {
public void hi() {
}
}
Hello
above is public
and therefore can be accessed by classes in other packages:
java
package xyz;
class Main {
void foo() {
// Main can access Hello
Hello h = new Hello();
}
}
field
and method
defined as public
can be accessed by other classes, provided that they first have permission to access class
:
java
package abc;
public class Hello {
public void hi() {
}
}
The above hi()
method is public
and can be called by other classes, provided that the Hello
class can be accessed first:
java
package xyz;
class Main {
void foo() {
Hello h = new Hello();
h.hi();
}
}
private
field
and method
defined as private
cannot be accessed by other classes:
java
package abc;
public class Hello {
// Cannot be called by other classes:
private void hi() {
}
public void hello() {
this.hi();
}
}
In fact, to be precise, private
access rights are limited to the interior of class
and have nothing to do with the order of method declaration. It is recommended to put the private
method at the end, because public
method defines the functions provided by the class to the outside world. When reading the code, you should pay attention to the public
method first:
java
package abc;
public class Hello {
public void hello() {
this.hi();
}
private void hi() {
}
}
Since Java supports nested classes, if a nested class is defined inside a class, then the nested class has access to private
:
java
public class Main {
public static void main(String[] args) {
Inner i = new Inner();
i.hi();
}
// private method:
private static void hello() {
System.out.println("private hello!");
}
// static inner class:
static class Inner {
public void hi() {
Main.hello();
}
}
}
class
defined inside a class
is called a nested class
. Java supports several nested classes.
protected
protected
works on inheritance relationships. Fields and methods defined as protected
can be accessed by subclasses, and subclasses of subclasses:
java
package abc;
public class Hello {
// protected method:
protected void hi() {
}
}
The protected
method above can be accessed by inherited classes:
java
package xyz;
class Main extends Hello {
void foo() {
// Can access protected methods:
hi();
}
}
package
Finally, package scope refers to a class
that allows access to class without public
or private
modifications in the same package
, as well as fields and methods without public
, protected
, or private
modifications.
java
package abc;
class Hello {
void hi() {
}
}
As long as you are in the same package, you can access class
, field
and method
of package permissions:
java
package abc;
class Main {
void foo() {
Hello h = new Hello();
h.hi();
}
}
Note that the package names must be exactly the same. There is no parent-child relationship between packages. com.apache
and com.apache.abc
are different packages.
local variables
Variables defined inside a method are called local variables. The scope of local variables starts from the declaration of the variable and ends at the corresponding block. Method parameters are also local variables.
java
package abc;
public class Hello {
void hi(String name) { // 1
String s = name.toLowerCase(); // 2
int len = s.length(); // 3
if (len < 10) { // 4
int p = 10 - len; // 5
for (int i=0; i<10; i++) { // 6
System.out.println(); // 7
} // 8
} // 9
} // 10
}
Let’s observe the hi()
method code above:
- The method parameter name is a local variable, and its scope is the entire method, that is, 1 ~ 10;
- The scope of variable s is from the point of definition to the end of the method, that is, 2 ~ 10;
- The scope of variable len is from the point of definition to the end of the method, that is, 3 ~ 10;
- The scope of variable p is from the definition point to the end of the if block, that is, 5 ~ 9;
- The scope of variable i is the for loop, that is, 6 ~ 8.
When using local variables, you should reduce the scope of local variables as much as possible and delay the declaration of local variables as much as possible.
final
Java also provides a final
modifier. final
does not conflict with access permissions and has many uses.
Decorating class
with final
prevents it from being inherited:
java
package abc;
// cannot be inherited:
public final class Hello {
private int n = 0;
protected void hi(int t) {
long i = t;
}
}
Decorating method
with final
prevents it from being overridden by subclasses:
java
package abc;
public class Hello {
// cannot be overwritten:
protected final void hi() {
}
}
Modifying field
with final
prevents it from being reassigned:
java
package abc;
public class Hello {
private final int n = 0;
protected void hi() {
this.n = 1; // error!
}
}
Decorating local variables with final
prevents them from being reassigned:
java
package abc;
public class Hello {
protected void hi(final int t) {
t = 1; // error!
}
}
Best practices
If you are not sure whether it is required to be public
, do not declare it as public
, that is, expose as few external fields and methods as possible.
Defining methods as package
permissions helps testing, because as long as the test class and the class under test are in the same package
, the test code can access the package
permission methods of the class under test.
A .java
file can only contain one public
class, but can contain multiple non-public classes. If there is a public
class, the file name must be the same as the name of the public
class.
Summary
Java's built-in access permissions include public
, protected
, private
and package
permissions;
Java variables defined inside a method are local variables. The scope of local variables starts from the variable declaration and ends with a block;
The final
modifier is not an access right, it can modify class
, field
and method
;
A .java
file can only contain one public
class, but can contain multiple non-public classes.