接口方法可以有主体吗?

我知道接口就像一个100% 纯抽象类。因此,它不能包含方法实现。但是,我看到了一个奇怪的代码。有人能解释一下吗?

代码片段:

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

编辑:

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

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

From Java 8 you can define static methods in interfaces in addition to default methods.

  • A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.

  • This makes it easier for you to organize helper methods in your libraries; you can keep static methods specific to an interface in the same interface rather than in a separate class.

  • The following example defines a static method that retrieves a ZoneId object corresponding to a time zone identifier; it uses the system default time zone if there is no ZoneId object corresponding to the given identifier. (As a result, you can simplify the method getZonedDateTime)

Here is code :

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));
}
}

See also

This is only possible in Java 8. In the Java 7 Language Specification §9.4, it explicitly states:

It is a compile-time error if a method declared in an interface is declared static, because static methods cannot be abstract.

So in Java 7, static methods in interfaces cannot exist.

If you go to the Java 8 Language Specification §9.4.3, you can see that it says:

A static method also has a block body, which provides the implementation of the method.

So it explicitly states that in Java 8, they can exist.

I even tried to run your exact code in Java 1.7.0_45, but it gave me the error "modifier static not allowed here".


Here is a quote directly from the Java 8 tutorial, Default Methods (Learning the Java Language > Interfaces and Inheritance):

Static Methods

In addition to default methods, you can define static methods in interfaces. (A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.) This makes it easier for you to organize helper methods in your libraries; you can keep static methods specific to an interface in the same interface rather than in a separate class. The following example defines a static method that retrieves a ZoneId object corresponding to a time zone identifier; it uses the system default time zone if there is no ZoneId object corresponding to the given identifier. (As a result, you can simplify the method 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));
}
}

Like static methods in classes, you specify that a method definition in an interface is a static method with the static keyword at the beginning of the method signature. All method declarations in an interface, including static methods, are implicitly public, so you can omit the public modifier.

For java version 7 or below, similar functionally you can achieve using nested class declared within interface body. and this nested class implements outer interface.

Example:

interface I1{
public void doSmth();


class DefaultRealizationClass implements  I1{


@Override
public void doSmth() {
System.out.println("default realization");
}
}
}

How do we use it in our code?

class MyClass implements I1{


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

Therefore default implementation encapsulated within interface.

Over the period java interfaces have evolved a lot and Java 8 completely changed the way interfaces were presumed.

Coming to question, yes we can have a method body in the interface.

whereas in java 8 we can have a method body in a static method and in the default method like the below example.

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();
}
}
}

we can also have the private method in the interfaces from java 9 onwards. like below code compiles well in java 9 and above versions but fails in java 8 and below

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();
}
}
 

References: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html [https://www.quora.com/profile/Rajat-Singh-187/Private-Method-in-the-Java-Interface]