Java 的 default 关键字

2025年1月6日 | 阅读 8 分钟

Java default 关键字 是一种访问修饰符。如果我们不为变量、方法、构造函数和类分配任何访问修饰符,默认情况下,它就被视为默认访问修饰符。default 关键字是一个多功能且强大的工具,在语言的各个方面都起着至关重要的作用。

注意事项

  • 默认访问修饰符只能在同一个包内访问。
  • 与 private 和 protected 不同,我们可以通过不为外部类分配任何访问修饰符来创建默认的外部类。在这种情况下,它不限制类名与程序名相同。
  • 如果我们重写任何方法,被重写的方法(即在子类中声明的方法)的访问级别不能比父类的方法更严格。因此,不允许使用 private 访问修饰符来修饰默认方法或变量。

在接口中使用 default 关键字

在 Java 中,接口传统上定义了类必须通过实现接口中声明的所有方法来遵守的契约。然而,当开发人员想要用新方法扩展接口,而又不强制所有实现类提供这些新方法的实现时,这会带来挑战。

default 关键字通过允许接口方法具有默认实现来解决此问题。这些方法隐式地是 public 的,并且如果需要,可以被实现类重写。通过允许向接口添加新方法而不会破坏现有代码,它有助于实现向后兼容性。

文件名:DefaultExample.java

输出

Car started.
Vehicle stopped.

带有 default 方法的多重继承

由于菱形问题,Java 不支持类的多重继承。然而,随着接口中 default 方法的引入,Java 有效地允许了行为的多重继承。如果一个类实现了具有冲突的 default 方法的多个接口,它必须显式地重写该方法,从而解决冲突。

文件名:UseOfDefault.java

输出

Interface1
Interface2

default 方法和接口演进

引入 default 方法的主要动机之一是为了在不破坏现有代码的情况下支持接口的演进。通过添加具有默认实现的具体方法,接口可以随着时间的推移而演进,同时保持与实现类的向后兼容性。

文件名:DefaultExample.java

输出

Area of rectangle: 15.0
Area of circle: 50.26548245743669
This is a rectangle with width 5.0 and height 3.0.
This is a shape.

在 switch 语句中使用 default 关键字

Java 12 引入了 switch 表达式,它通过允许 switch 表达式返回值来增强传统的 switch 语句。default 关键字在 switch 表达式中用于指定当没有其他 case 匹配时执行的默认 case。

文件名:SwitchDefault.java

输出

Day name: Thursday

default 关键字示例

示例 1

让我们看一个示例,以确定默认变量是否可以在包外访问。

文件名:A.java

文件名:DefaultExample1.java

输出

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The field A.msg is not visible

示例 2

让我们看一个示例,以确定默认变量是否可以在包内类外访问。

文件名:DefaultExample2.java

输出

Try to access the default variable outside the class within the package

示例 3

让我们看一个示例,以确定默认方法是否可以在包外访问。

文件名:A.java

文件名:DefaultExample3.java

输出

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method msg() from the type A is not visible

示例 4

让我们看一个示例,以确定是否可以使用继承在包外访问默认方法。

文件名:A.java

文件名:DefaultExample4.java

输出

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method msg() from the type A is not visible

示例 5

让我们看一个示例,以确定我们是否可以使用默认外部类。

文件名:DefaultExample5.java

输出

Try to access outer default classs

示例 6

让我们看一个示例,以确定我们是否可以从类外部创建默认构造函数的实例。

文件名:com.java

文件名:DefaultExample6.java

输出

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The constructor A(String) is not visible

示例 7

让我们看一个示例,以确定是否可以使用默认访问修饰符将默认方法重写到子类。

文件名:A.java

文件名:DefaultExample7.java

输出

Try to access the overridden method

示例 8

让我们看一个示例,以确定是否可以使用 private 访问修饰符将默认方法重写到子类。

文件名:DefaultExample8.java

输出

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Cannot reduce the visibility of the inherited method from A

示例 9

让我们看一个示例,以确定是否可以使用默认访问修饰符将默认方法重写到子类。

文件名:DefaultExample9.java

输出

Try to access the overridden method

示例 10

让我们看一个示例,以确定是否可以使用 public 访问修饰符将默认方法重写到子类。

文件名:DefaultExample10.java

输出

Try to access the overridden method