我知道接口就像一个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您可以在接口中定义除了默认方法之外的静态方法。
-
静态方法是与定义它的类相关联而不是与任何对象相关联的方法。类的每个实例都共享它的静态方法。
-
这使得你更容易在你的库中组织helper方法;
您可以将特定于接口的静态方法保留在同一个接口中,而不是在单独的类中。 下面的示例定义了一个静态方法,用于检索与时区标识符对应的
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 docs for interface methods
关于Java 8中所有有趣的事情,请阅读
这只能在Java 8中实现。在Java 7语言规范§9.4中,它明确地声明:
如果在接口中声明的方法声明为静态,则会导致编译时错误,因为静态方法不能是抽象的。
所以在Java 7中,接口中的静态方法不能存在。
如果你去Java 8语言规范§9.4.3,你可以看到它说:
静态方法也有一个块体,它提供了方法的实现。
所以它明确地声明了在Java 8中,它们可以存在。
我甚至试图在Java 1.7.0_45中运行您的确切代码,但它给了我错误"此处不允许修改符静态"。
这是直接引用自Java 8教程,默认方法(学习Java语言>接口和继承):
静态方法除了默认方法之外,还可以在接口。静态方法是与对象相关联的方法类中定义它而不是使用任何对象。每一个类的实例共享其静态方法。)这样就容易多了供您在库中组织helper方法;你可以继续而不是在同一接口中特定于接口的静态方法而不是单独上课。下面的例子定义了一个静态对象方法,检索与时间相对应的
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();
}
}
在此期间,java接口发生了很大的变化,java 8完全改变了接口的假定方式。
说到问题,是的,我们可以在接口中有一个方法体。
而在java 8中,可以在静态方法和默认方法中拥有方法体,如下例所示。
interface CheckMyEvolution{
default void whatsNew() {
System.out.print("Hello there!Check my Evolution");
}
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();
}
}
}
也可以在java 9以后的接口中使用私有方法。下面的代码在java 9及以上版本中可以很好地编译,但在
java 8及以下版本中失败interface CheckMyEvolution{
default void whatsNew() {
checkIt();
}
// Private method
private void checkIt() {
System.out.println("Hello there! I can have private method now. Make sure you are using JDK 9 or Above.");
}
}
public class CheckMyEvolutionImpl implements CheckMyEvolution{
public static void main(String[] args) {
CheckMyEvolution evolution= new CheckMyEvolutionImpl();
evolution.whatsNew();
}
}
引用:https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.htmldiv [https://www.quora.com/profile/Rajat-Singh-187/Private-Method-in-the-Java-Interface]