我知道界面就像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));
}
}
这只能在Java 8中实现。在Java 7 Language Specification §9.4中,它明确指出:
如果在接口中声明的方法声明为static,则这是一个编译时错误,因为静态方法不能是抽象的。
所以在Java 7中,接口中的静态方法不可能存在。
如果你去Java 8 Language Specification §9.4.3,你可以看到它说:
静态方法还有一个块体,它提供了该方法的实现。
因此它明确指出在Java 8中它们可以存在。
我甚至试图在Java 1.7.0_45中运行您的确切代码,但它给了我错误“modifier static not allowed here”。
这是直接来自Java 8教程Default Methods (Learning the Java Language > Interfaces and Inheritance)的引用:
静态方法
除了默认方法,您还可以在接口中定义static methods。 (静态方法是一种与定义它的类相关联的方法,而不是与任何对象相关联。该类的每个实例都共享其静态方法。)这使您可以更轻松地在库中组织辅助方法;您可以在同一个接口中保留特定于接口的静态方法,而不是在单独的类中。以下示例定义一个静态方法,该方法检索与时区标识符对应的
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
关键字。接口中的所有方法声明(包括静态方法)都隐式为public
,因此您可以省略public
修饰符。
对于java版本7或更低版本,在功能上类似,您可以使用在接口体内声明的嵌套类来实现。这个嵌套类实现了外部接口。
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();
}
}
因此默认实现封装在接口中。