0%

访问权限

Java 访问权限修饰符详解

在 Java 中,访问权限修饰符用于控制类、属性、方法的可见范围,是封装特性的核心实现手段。合理使用访问权限可以隐藏内部实现细节、保护数据安全,并降低代码耦合度。Java 提供四种访问权限,从最大到最小依次为:publicprotected包访问权限(default,无修饰符)private

包(Package):访问权限的基础

包是类的组织单位,用于避免类名冲突并划分访问边界。一个类的全名是 “包名 + 类名”(如 java.util.ArrayList)。通过 import 语句可以简化类的使用(如 import java.util.ArrayList)。

  • 同包类:位于同一包下的类,默认具有包访问权限。
  • 不同包类:位于不同包下的类,需通过 publicprotected 权限才能访问。

四种访问权限详解

1. public(公共权限)

  • 可见范围:所有类(本类、同包类、子类、非子类)均可访问。
  • 适用场景:暴露给外部的接口(如 java.util.Listadd 方法)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class PublicDemo {
public String publicField = "公共属性";

public void publicMethod() {
System.out.println("公共方法");
}
}

// 任意类均可访问
public class OtherClass {
public static void main(String[] args) {
PublicDemo demo = new PublicDemo();
System.out.println(demo.publicField); // 合法
demo.publicMethod(); // 合法
}
}

2. protected(保护权限)

  • 可见范围:本类、同包类、子类(无论是否同包)可访问,非子类不可访问。
  • 适用场景:仅允许子类继承或同包类协作的成员(如模板方法中的辅助方法)。
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
package com.example.parent;
public class ProtectedDemo {
protected String protectedField = "保护属性";

protected void protectedMethod() {
System.out.println("保护方法");
}
}

// 同包类:可访问
package com.example.parent;
public class SamePackageClass {
public static void main(String[] args) {
ProtectedDemo demo = new ProtectedDemo();
System.out.println(demo.protectedField); // 合法
}
}

// 不同包子类:可访问
package com.example.child;
import com.example.parent.ProtectedDemo;
public class SubClass extends ProtectedDemo {
public void test() {
System.out.println(protectedField); // 合法(继承自父类)
protectedMethod(); // 合法
}
}

// 不同包非子类:不可访问
package com.example.other;
import com.example.parent.ProtectedDemo;
public class OtherClass {
public static void main(String[] args) {
ProtectedDemo demo = new ProtectedDemo();
// System.out.println(demo.protectedField); // 编译报错
}
}

3. 包访问权限(default,无修饰符)

  • 可见范围:仅本类和同包类可访问,子类(不同包)和非子类不可访问。
  • 适用场景:包内部的辅助类或成员,不对外暴露(如工具类的内部方法)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.pkg;
class DefaultDemo { // 无修饰符,仅同包可见
String defaultField = "包访问属性";

void defaultMethod() {
System.out.println("包访问方法");
}
}

// 同包类:可访问
package com.example.pkg;
public class SamePackageClass {
public static void main(String[] args) {
DefaultDemo demo = new DefaultDemo();
System.out.println(demo.defaultField); // 合法
}
}

// 不同包类:不可访问
package com.example.other;
import com.example.pkg.DefaultDemo; // 编译报错(DefaultDemo 不可见)
public class OtherClass {
// 无法访问 DefaultDemo
}

4. private(私有权限)

  • 可见范围:仅本类可访问,其他任何类(包括同包类和子类)均不可访问。
  • 适用场景:类的内部状态(属性)或私有方法,完全隐藏实现细节(如封装中的 private 属性)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class PrivateDemo {
private String privateField = "私有属性";

private void privateMethod() {
System.out.println("私有方法");
}

// 本类内部可访问
public void accessPrivate() {
System.out.println(privateField); // 合法
privateMethod(); // 合法
}
}

public class OtherClass {
public static void main(String[] args) {
PrivateDemo demo = new PrivateDemo();
// System.out.println(demo.privateField); // 编译报错
// demo.privateMethod(); // 编译报错
demo.accessPrivate(); // 合法(通过公共方法间接访问)
}
}

访问权限对比表

修饰符 本类 同包类 不同包子类 不同包非子类
public ✔️ ✔️ ✔️ ✔️
protected ✔️ ✔️ ✔️
包访问(default) ✔️ ✔️
private ✔️

使用原则与最佳实践

  1. 最小权限原则:尽可能使用小的访问权限(如能 private 就不 protected),减少外部依赖。

  2. 属性私有化:类的属性通常用private修饰,通过public的getter/setter方法暴露必要的访问,便于添加校验逻辑。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class User {
    private String name; // 私有属性

    public String getName() { // 公共 getter
    return name;
    }

    public void setName(String name) { // 公共 setter,可添加校验
    if (name == null || name.isEmpty()) {
    throw new IllegalArgumentException("姓名不能为空");
    }
    this.name = name;
    }
    }
  3. 接口方法公开:对外提供的接口方法用 public,内部辅助方法用 private 或包访问权限。

  4. 谨慎使用 protectedprotected 成员会增加类之间的耦合,仅在需要被子类继承时使用。

  5. 避免滥用 public:类的内部实现细节(如临时变量、辅助方法)不应设为 public,防止外部依赖导致后续修改困难

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10