Java中public、protected、package - private和private的区别

Java中public、protected、package - private和private的区别

技术背景

在Java编程中,访问修饰符是实现封装的重要手段,它可以控制类、方法和变量的访问权限,提高代码的安全性和可维护性。Java提供了四种访问修饰符:publicprotectedpackage - private(默认,无修饰符)和private,了解它们之间的区别对于编写高质量的Java代码至关重要。

实现步骤

1. 明确不同访问修饰符的作用范围

修饰符类内部同一包内不同包的子类全局
public✔️✔️✔️✔️
protected✔️✔️✔️
package - private(无修饰符)✔️✔️
private✔️

2. 不同访问修饰符的详细解释

  • private:只能在声明它的类内部访问。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A {
private int data = 40;
private void msg() {
System.out.println("Hello java");
}
}

public class Simple {
public static void main(String args[]) {
A obj = new A();
// 编译错误
System.out.println(obj.data);
// 编译错误
obj.msg();
}
}
  • package - private(无修饰符):可以被同一包内的其他类访问。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Saved in file A.java
package pack;

class A {
void msg() {
System.out.println("Hello");
}
}

// Saved in file B.java
package mypack;
import pack.*;

class B {
public static void main(String args[]) {
// 编译错误
A obj = new A();
// 编译错误
obj.msg();
}
}
  • protected:可以被同一包内的类以及不同包的子类访问。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Saved in file A.java
package pack;
public class A {
protected void msg() {
System.out.println("Hello");
}
}

// Saved in file B.java
package mypack;
import pack.*;

class B extends A {
public static void main(String args[]) {
B obj = new B();
obj.msg();
}
}
  • public:可以被任何类访问。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Saved in file A.java
package pack;
public class A {
public void msg() {
System.out.println("Hello");
}
}

// Saved in file B.java
package mypack;
import pack.*;

class B {
public static void main(String args[]) {
A obj = new A();
obj.msg();
}
}

核心代码

以下是一个包含不同访问修饰符的完整类示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.example;

// 公共类
public class MainClass {
// 公共字段
public int publicField = 1;
// 受保护字段
protected int protectedField = 2;
// 默认(包私有)字段
int defaultField = 3;
// 私有字段
private int privateField = 4;

// 公共方法
public void publicMethod() {
System.out.println("This is a public method.");
}

// 受保护方法
protected void protectedMethod() {
System.out.println("This is a protected method.");
}

// 默认(包私有)方法
void defaultMethod() {
System.out.println("This is a default method.");
}

// 私有方法
private void privateMethod() {
System.out.println("This is a private method.");
}

public static void main(String[] args) {
MainClass obj = new MainClass();
// 可以访问所有修饰符的成员
System.out.println(obj.publicField);
System.out.println(obj.protectedField);
System.out.println(obj.defaultField);
System.out.println(obj.privateField);
obj.publicMethod();
obj.protectedMethod();
obj.defaultMethod();
obj.privateMethod();
}
}

最佳实践

  • 遵循“最小知识原则”,即尽量让成员的可见性最小化。优先使用private,仅在必要时增加可见性。
  • 如果成员仅在类内部使用,应声明为private
  • 如果成员仅在同一包内使用,使用默认(无修饰符)。
  • 如果成员需要被子类访问,但不希望全局可访问,使用protected
  • 如果成员需要被所有类访问,使用public

常见问题

1. 为什么Java的默认访问修饰符是package - private

默认使用package - private可以在一定程度上限制类的访问范围,提高代码的内聚性和安全性。同一包内的类可以相互协作,而外部包的类无法直接访问这些类的成员。

2. protected修饰符的复杂情况

protected修饰符的访问规则比较复杂,例如在不同包的子类中,不能通过父类的引用访问受保护成员,只能通过子类自身的实例或thissuper关键字访问。

3. 访问修饰符对类和接口的限制

对于顶级类,只能使用publicpackage - private修饰符;protectedprivate不能用于顶级类,因为在包级别使用它们是多余的。接口中的方法默认是public的,不能使用其他访问修饰符。


Java中public、protected、package - private和private的区别
https://119291.xyz/posts/2025-05-09.differences-between-public-protected-package-private-and-private-in-java/
作者
ww
发布于
2025年5月9日
许可协议