杰瑞科技汇

Java default权限到底有什么用?

什么是 default 权限?

default 权限,也常被称为 包私有权限,是 Java 访问修饰符中的一种,当一个类、成员变量(字段)或方法没有显式地使用任何访问修饰符(如 public, protected, private)时,它就拥有了 default 权限。

关键点: default 权限不是一个关键字,而是没有关键字时的一种默认状态。


访问规则详解

default 权限的核心规则是:只有同一个包内的类才能访问

让我们通过一个表格来对比四种访问修饰符,会更清晰:

修饰符 同一类中 同一包中不同类 不同包的子类 不同包的非子类
public ✔️ ✔️ ✔️ ✔️
protected ✔️ ✔️ ✔️
default ✔️ ✔️
private ✔️

代码示例

为了更好地理解,我们创建几个类来演示。

项目结构

假设我们有以下包结构:

src/
├── com/
│   └── example/
│       ├── Animal.java
│       ├── Dog.java
│       └── Main.java
└── com/
    └── other/
        └── Cat.java

示例代码

com.example.Animal.java (同一个包中的基类)

package com.example;
// 这个类没有 public 修饰符,所以它只能在 com.example 包内被访问。
class Animal {
    // default 权限的成员变量
    String name;
    // default 权限的方法
    void eat() {
        System.out.println("This animal is eating.");
    }
    // public 权限的方法,用于外部调用
    public void displayInfo() {
        System.out.println("Animal's name: " + this.name);
    }
}

com.example.Dog.java (同一个包中的子类)

package com.example;
// Dog 和 Animal 在同一个包下
public class Dog extends Animal {
    public Dog(String name) {
        // 可以访问父类的 default 成员
        this.name = name;
    }
    public void bark() {
        // 可以调用父类的 default 方法
        eat(); 
        System.out.println(name + " says: Woof!");
    }
}

com.example.Main.java (同一个包中的其他类)

package com.example;
// Main, Animal, Dog 都在 com.example 包下
public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.name = "Generic Animal"; // 可以访问 default 成员
        animal.eat();                 // 可以调用 default 方法
        animal.displayInfo();
        System.out.println("--------------------");
        Dog dog = new Dog("Buddy");
        dog.bark(); // 通过 Dog 类间接访问了 Animal 的 default 成员和方法
    }
}

com.other.Cat.java (不同包中的类)

package com.other;
// Cat 和 Animal 不在同一个包下
public class Cat {
    public void tryToAccessAnimal() {
        Animal animal = new Animal(); // 编译错误!因为 Animal 类是 default 权限,不能跨包访问。
        // 以下所有行都会导致编译错误
        // animal.name = "Whiskers"; // 编译错误
        // animal.eat();             // 编译错误
        // animal.displayInfo();     // 编译错误
    }
}

运行结果

当你运行 com.example.Main 时,它会正常工作并输出:

This animal is eating.
Animal's name: Generic Animal
--------------------
This animal is eating.
Buddy says: Woof!

当你尝试编译 com.other.Cat.java 时,编译器会报错,提示 Animalpublic 或在 com.other 包中。


何时使用 default 权限?

default 权限是实现封装模块化的重要工具。

包内实现细节的隐藏

这是 default 权限最常见的用途,一个包通常代表一个功能模块或一个组件,你可以将模块内部的类、接口、方法和字段设置为 default 权限,以表明它们是模块的内部实现,不应该被模块外的代码直接依赖。

这样做的好处是:

  • 降低耦合性:外部代码无法直接访问你的内部实现,当你需要重构或修改内部实现时,不会影响到外部代码。
  • 清晰的边界:它向其他开发者明确传达了“这是我的内部API,请勿触碰”的信号。

接口中的 default 方法

从 Java 8 开始,default 关键字有了另一个用途:可以在接口中定义带有 default 实现的方法。

注意:这和访问修饰符的 default 是两个完全不同的概念!

public interface MyInterface {
    // 这是一个抽象方法,没有实现
    void abstractMethod();
    // 这是一个 default 方法,有默认实现
    // 它可以被实现该接口的类直接继承,也可以被覆盖
    default void defaultMethod() {
        System.out.println("This is a default method in the interface.");
    }
}
public class MyClass implements MyInterface {
    // 必须实现 abstractMethod
    @Override
    public void abstractMethod() {
        System.out.println("Implementing abstractMethod.");
    }
    // 可以选择不实现 defaultMethod,直接使用默认实现
}
public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.abstractMethod(); // 输出: Implementing abstractMethod.
        obj.defaultMethod(); // 输出: This is a default method in the interface.
    }
}

特性 描述
名称 default 权限,也称为包私有权限
修饰符 不使用任何访问修饰符(public, protected, private)。
访问范围 仅限于同一个包内的类可以访问。
可以声明 default 类,该类只能被同包内的其他类访问和继承。
成员(变量/方法) 可以声明 default 成员,该成员只能被同包内的类访问。
接口 接口本身必须是 public 的,不能是 default 的。
接口方法 接口中的 default 方法(Java 8+)是一种带有默认实现的方法,与访问修饰符的 default 无关。
核心思想 封装,用于隐藏包的实现细节,保护模块的完整性,降低外部依赖。

理解 default 权限是编写健壮、可维护 Java 代码的基础,它帮助你构建清晰的模块边界,是良好封装实践的一部分。

分享:
扫描分享到社交APP
上一篇
下一篇