问题
I know that an interface is like a 100% pure abstract class. So, it can't have method implementation in it. But, I saw a strange code. Can anyone explain it?
Code Snippet:
interface Whoa {
public static void doStuff() {
System.out.println("This is not default implementation");
}
}
EDIT:
My IDE is Intellij Idea 13.1. The project SDK is java 7 <1.7.0_25>. The IDE is not showing any compiler error. But, When I compile the code at command line I am getting the following message.
Whoa.java:2: error: modifier static not allowed here public static void doStuff() { ^
回答1:
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 noZoneId
object corresponding to the given identifier. (As a result, you can simplify the methodgetZonedDateTime
)
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
Oracle docs for interface methods
For all interesting things in Java 8 read Everything about Java 8
回答2:
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 methodgetZonedDateTime
):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 implicitlypublic
, so you can omit thepublic
modifier.
回答3:
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.
来源:https://stackoverflow.com/questions/22713652/can-an-interface-method-have-a-body