【问题标题】:Static methods in java interfacejava接口中的静态方法
【发布时间】:2014-06-02 15:06:50
【问题描述】:

据我所知,您不能在接口主体中声明静态方法。然而,我偶然在http://docs.oracle.com/ 网站上发现了一段奇特的代码。这是link

public interface TimeClient 
{
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
                           int hour, int minute, int second);
LocalDateTime getLocalDateTime();

static ZoneId getZoneId (String zoneString) {
    try {
        return ZoneId.of(zoneString);
    } catch (DateTimeException e) {
        System.err.println("Invalid time zone: " + zoneString +
            "; using default time zone instead.");
        return ZoneId.systemDefault();
    }
}

default ZonedDateTime getZonedDateTime(String zoneString) {
    return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

这个interface 有一个static 方法getZoneId

我迷路了……谁能解释一下

【问题讨论】:

  • 可以在从 Java 8 开始的接口中声明静态方法。还要注意 getZoneDateTime() 方法(虚拟扩展方法,也是 Java 8 中的新方法)。
  • 你没有看到 Java 8 的新特性列表吗?检查一下。

标签: java interface static-methods


【解决方案1】:

您在这里见证了 Java 8 的两个新特性:

  • 接口中的静态方法,
  • 虚拟扩展方法。

在您提供的代码示例中,getZoneId() 说明了第一个新颖性,.getZoneDateTime() 说明了第二个。

第二个特别是允许使用诸如.stream() 之类的补充方法扩展Collection 接口,例如, 不会破坏向后兼容性。请参阅here 获取插图。

第一个允许避免编写“方法包”类,这些类通常只是为了在接口上提供实用静态方法而存在。一个这样的例子是 Guava's Functions class(不要与 Java 8 的 Function 混在一起,它基本上是从 Guava 偷来的,还有 Predicate 和其他一些)

【讨论】:

    【解决方案2】:

    Java 8 现在有了在接口中实现“默认”方法的想法:

    http://blog.hartveld.com/2013/03/jdk-8-13-interface-default-method.html

    【讨论】:

    • 大家都正确回答了我的问题。不过你是第一个。
    • 并非如此,默认方法和静态方法之间存在差异,所以我们不要混淆这些(和其他用户)。这也许是一个很好的指针,但不是一个正确的答案。
    • @virgo47 你是对的,我不确定我在这里做什么。我查看了问题最初是否引用了默认方法,但没有。我会删除这个。呃,不能删除,因为它被接受了:(
    【解决方案3】:

    从 Java 8 开始,您可以做到这一点。您的 sn-p 来自的official tutorial(已针对 Java 8 进行了更新)说得最好:

    接口体可以包含抽象方法、默认方法和静态方法。接口中的抽象方法后跟分号,但没有大括号(抽象方法不包含实现)。默认方法使用default 修饰符定义,静态方法使用static 关键字定义。接口中的所有抽象、默认和静态方法都是隐式公共的,因此您可以省略 public 修饰符。

    或者来自 Java 8 的 JLS section 9.4:

    默认方法是在带有default 修饰符的接口中声明的方法;它的主体总是由一个块表示。它为任何实现接口而不重写方法的类提供默认实现。默认方法不同于在类中声明的具体方法。

    ...

    接口可以声明静态方法,在调用时无需引用特定对象。

    【讨论】:

      【解决方案4】:

      来自 Java 语言规范(Java SE 8 版):http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4

      接口可以声明静态方法,在调用时无需引用特定对象。

      【讨论】:

        【解决方案5】:

        在 Java 8 中,接口可以具有静态方法,以及具有默认实现的可覆盖方法。他们仍然不能有实例字段。这些特性是 lambda 表达式支持的一部分,您可以在 H 部分了解更多信息。 JSR 335

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-16
          • 1970-01-01
          • 2014-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-15
          • 1970-01-01
          相关资源
          最近更新 更多