一个接口方法可以有一个正文?

我知道一个接口就像是一个100%纯粹的抽象类。 所以,它不能有方法的实现。 但是,我看到一个奇怪的代码。 任何人都可以解释吗?

代码片段:

interface Whoa { public static void doStuff() { System.out.println("This is not default implementation"); } } 

编辑:

我的IDE是Intellij Idea 13.1。 项目SDK是java 7 <1.7.0_25>。 IDE没有显示任何编译器错误。 但是,当我在命令行编译代码时,我收到以下消息。

 Whoa.java:2: error: modifier static not allowed here public static void doStuff() { ^ 

Java 8开始 ,除了默认方法之外,您还可以在接口中定义静态方法。

  • 静态方法是一种与其定义的类关联的方法,而不是任何对象。 每个类的实例共享其静态方法。

  • 这使您更容易在您的库中组织帮助器方法; 您可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中。

  • 以下示例定义了一个静态方法,用于检索与时区标识符对应的ZoneId对象; 如果没有对应于给定标识符的ZoneId对象,则使用系统默认时区。 (因此,您可以简化getZonedDateTime方法)

这是代码:

 public interface TimeClient { // ... static public 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 public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } } 

也可以看看

  • Oracle文档的接口方法

  • 对于Java 8中所有有趣的东西,请阅读关于Java 8的所有内容

这只能在Java 8中实现。在Java 7 Language Specification§9.4中 ,它明确指出:

如果在接口中声明的方法被声明为静态,那么这是一个编译时错误,因为静态方法不能是抽象的。

所以在Java 7中,接口中的静态方法是存在的。

如果你转到Java 8语言规范§9.4.3 ,你可以看到它说:

一个静态方法也有一个块体,它提供了方法的实现。

所以它明确指出,在Java 8中,它们可以存在。

我甚至试图在Java 1.7.0_45中运行你的确切的代码,但它给了我错误“修改器静态不允许在这里”。


这里直接引用了Java 8教程中的默认方法(学习Java语言>接口和inheritance) :

静态方法

除了默认方法之外,您还可以在接口中定义静态方法 。 (静态方法是一个与定义它的类相关联的方法,而不是与任何对象相关联的类的每个实例共享其静态方法)这使得您可以更轻松地在库中组织帮助器方法; 您可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中。 以下示例定义了一个静态方法,用于检索与时区标识符对应的ZoneId对象; 如果没有对应于给定标识符的ZoneId对象,则使用系统默认时区。 (因此,您可以简化getZonedDateTime方法):

 public interface TimeClient { // ... static public 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 public ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } } 

与类中的静态方法类似,您可以指定接口中的方法定义是在方法签名开始处使用static关键字的static方法。 接口中的所有方法声明(包括静态方法)都是隐式public ,所以可以省略public修饰符。

对于Java版本7或更低版本,类似的function可以使用在接口体内声明的嵌套类来实现。 而这个嵌套类实现了外部接口。

例:

 interface I1{ public void doSmth(); class DefaultRealizationClass implements I1{ @Override public void doSmth() { System.out.println("default realization"); } } } 

我们如何在代码中使用它?

 class MyClass implements I1{ @Override public void doSmth() { new I1.DefaultRealizationClass().doSmth(); } } 

因此默认实现封装在接口中。