Java 接口中的静态方法

Java 接口中的静态方法,用户希望为接口添加一个类级别(class level)的工具方法和相应的实现,将接口方法声明为 static,并以常规方式添加实现。Java 类的静态成员是类级别的。换言之,静态成员与整个类相关联,而不是与特定的实例相关联。但从设计的角度看,静态成员在接口中的使用是有问题的。

Java 接口中的静态方法 问题描述

用户希望为接口添加一个类级别(class level)的工具方法和相应的实现。

Java 接口中的静态方法 解决方案

将接口方法声明为 static,并以常规方式添加实现。

Java 接口中的静态方法 具体实例

Java 类的静态成员是类级别的。换言之,静态成员与整个类相关联,而不是与特定的实例相关联。但从设计的角度看,静态成员在接口中的使用是有问题的,举例如下。

  • 当多个不同的类实现接口时,类级别成员指的是什么?
  • 类是否需要通过实现接口来使用静态方法?
  • 类中的静态方法是通过类名访问的。如果类实现了一个接口,那么静态方法是通过类名还是接口名来调用呢?

为解决这些问题,Java 开发团队尝试了几种不同的方案。
在 Java 8 之前,接口完全不支持使用静态成员,不过这导致了工具类的产生,这是一种只包含静态方法的类。java.util.Collections 就是一种典型的工具类,它不仅包括用于排序和搜索的方法,也定义了采用同步或不可修改的类型包装集合的方法。在 NIO 包中,另一种工具类是 java.nio.file.Paths,它只包括从字符串或 URI 中解析 Path 实例的两个静态方法。
而在 Java 8 中,我们可以随时为接口添加静态方法,步骤如下。

  • 为方法添加 static 关键字。
  • 提供一种无法被重写的实现。此时,静态方法类似于默认方法,包含在 Javadoc 的 Default Methods(默认标签)中。
  • 通过接口名访问方法。类需要通过实现接口来使用静态方法。

java.util.Comparator 接口定义的 comparing 方法就是一种实用的静态方法,它包括 comparingIntcomparingLongcomparingDouble 等三种基本变体。此外,Comparator 接口还包括 naturalOrderreverseOrder 两种静态方法。例 1-28 给出了这些方法的用法。

例 1-28 字符串排序

List<String> bonds = Arrays.asList("Connery", "Lazenby", "Moore",
    "Dalton", "Brosnan", "Craig");

List<String> sorted = bonds.stream()
    .sorted(Comparator.naturalOrder())                 ➊
    .collect(Collectors.toList());
// [Brosnan, Connery, Craig, Dalton, Lazenby, Moore]

sorted = bonds.stream()
    .sorted(Comparator.reverseOrder())                 ➋
    .collect(Collectors.toList());
// [Moore, Lazenby, Dalton, Craig, Connery, Brosnan]

sorted = bonds.stream()
    .sorted(Comparator.comparing(String::toLowerCase)) ➌
    .collect(Collectors.toList());
// [Brosnan, Connery, Craig, Dalton, Lazenby, Moore]

sorted = bonds.stream()
    .sorted(Comparator.comparingInt(String::length))   ➍
    .collect(Collectors.toList());
// [Moore, Craig, Dalton, Connery, Lazenby, Brosnan]

sorted = bonds.stream()
    .sorted(Comparator.comparingInt(String::length)    ➎
        .thenComparing(Comparator.naturalOrder()))
    .collect(Collectors.toList());
// [Craig, Moore, Dalton, Brosnan, Connery, Lazenby]

❶ 自然顺序(字典序)
❷ 反向顺序(字典序)
❸ 按小写名称排序
❹ 按姓名长度排序
❺ 按姓名长度排序,如果长度相同则按字典序排序
本例显示了如何利用 Comparator 接口提供的静态方法对一份演员名单进行排序,名单中出现的演员是这些年来詹姆斯 • 邦德的扮演者。有关比较器的详细讨论,请参见范例 利用比较器实现排序

由于接口中有静态方法,我们不必创建单独的工具类。但需要的话,仍然可以创建工具类。
请注意以下几点:

  • 静态方法必须有一个实现
  • 无法重写静态方法
  • 通过接口名调用静态方法
  • 无须实现接口以使用静态方法
赞(5)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Java 实例