-2

While browsing the source of java.util.Collections interface of java 1.8, I noticed this,

default boolean removeIf(Predicate<? super E> filter) 
{
 ....
}

So as of 1.8, java allows methods in interfaces to define bodies. However there a few semantic peculiarities; if the method is public I need to explicitly mention it as static too, this is understandable, but why is this not enforced on default? in fact specifying static with default gives an error. What purpose does this serve?

EDIT: seeing the number of downvotes, I would encourage you to try this out first before jumping to conclusions in disbelief

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Rnet
  • 4,796
  • 9
  • 47
  • 83
  • 3
    _if the method is public I need to explicitly mention it also static_ Are you sure? – Sotirios Delimanolis Apr 01 '15 at 19:07
  • Yes, I get an error "interface abstract methods cannot have body" – Rnet Apr 01 '15 at 19:09
  • 1
    You're not compiling with Java 8. A `default` method cannot be `static`. `default` methods are implicitly `public`. – Sotirios Delimanolis Apr 01 '15 at 19:10
  • Are you compiling with Eclipse or the Oracle JDK (or a different JDK)? – Mark Rotteveel Apr 01 '15 at 19:11
  • @SotiriosDelimanolis I'm, using version 1.8.0_25, the keyword static needs to be there if it is public – Rnet Apr 01 '15 at 19:13
  • @MarkRotteveel Oracle JDK – Rnet Apr 01 '15 at 19:14
  • [_It is a compile-time error if a method is declared with more than one of the modifiers `abstract`, `default`, or `static`._](http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4) and [_A member type declaration in an interface is implicitly `public` and `static`. It is permitted to redundantly specify either or both of these modifiers._](http://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.5) – Sotirios Delimanolis Apr 01 '15 at 19:17
  • 1
    *All method declarations in an interface, including default methods, are implicitly public* No mention about static. – WonderWorld Apr 01 '15 at 19:34
  • 1
    @SotiriosDelimanolis Your second JLS quote from section 9.5 applies to *member types*, that is, nested classes and interfaces, which is different from what's being discussed here. The quote from section 9.4 is of course relevant. – Stuart Marks Apr 01 '15 at 23:47
  • @StuartMarks Oops, blind ctrl+f'ing through the JLS is not safe. – Sotirios Delimanolis Apr 01 '15 at 23:48

2 Answers2

2

I tried compiling the following test interface:

public interface TestInterface {
                    void m();
           abstract void am();
           default  void dm() { }
           static   void sm() { }
    public          void pm();
    public abstract void pam(); 
    public default  void pdm() { }
    public static   void psm() { }
}

using the JDKs I happened to have lying around, namely: 8, 8u5, 8u11, 8u25, 8u40, and a jdk9-dev build from a couple days ago. It compiled successfully on all of these versions.

As others have noted, methods in an interface are all public, regardless of whether or not public is specified. In addition, a method can either be abstract, default, or static, and a method is abstract if none of these is specified. (JLS 9.4) Finally, methods declared default or static must have a block { ... } for the body, whereas abstract methods (whether declared or not) must have a semicolon ; as the body. (JLS 9.4.3)

if the method is public I need to explicitly mention it as static too ... but why is this not enforced on default? (from comment) the keyword static needs to be there if it is public.

I don't see this. All interface methods are public, whether or not they explicitly declared as such. This is orthogonal to the method being static or default.

in fact specifying static with default gives an error.

Yes, a method can be static or default but not both.

I get an error "interface abstract methods cannot have body"

If you're getting this error, you must be specifying a block { ... } as the body for an abstract method, regardless of whether or not the method is explicitly declared as abstract.

(JDK 9 has recently added support for private methods in interfaces.)

Community
  • 1
  • 1
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
0

So as of 1.8, java allows methods in interfaces to define bodies

No, it doesn't. You can - must actually - define a body for methods marked as default or static. But you can't define a body for an abstract method, which is what you tried to do.

A method can be either abstract, default or static. If no keyword is used then it's abstract. abstract means having no implementation. default means having an implementation that is used if a class doesn't provide its own one. A method marked as static is not inherited to a class.

So they are all different, serve different purposes and cannot be mixed. A default method should be inherited so it cannot be static.

a better oliver
  • 26,330
  • 2
  • 58
  • 66