92

There have been a few questions asked here about why you can't define static methods within interfaces, but none of them address a basic inconsistency: why can you define static fields and static inner types within an interface, but not static methods?

Static inner types perhaps aren't a fair comparison, since that's just syntactic sugar that generates a new class, but why fields but not methods?

An argument against static methods within interfaces is that it breaks the virtual table resolution strategy used by the JVM, but shouldn't that apply equally to static fields, i.e. the compiler can just inline it?

Consistency is what I desire, and Java should have either supported no statics of any form within an interface, or it should be consistent and allow them.

skaffman
  • 398,947
  • 96
  • 818
  • 769
  • The fields are defined while the method has no body. Attempting to invoke the method will cause an error, whilst the variables will always be present: whether default or defined. –  Mar 22 '12 at 15:44
  • 1
    http://bugs.sun.com/view_bug.do?bug_id=4093687 - closed will not fix w/ 200+ votes, and that was 1997... – bestsss Jul 23 '12 at 20:50
  • @erickson - why do you say that its an interview failing answer ? – Erran Morad May 07 '14 at 19:42
  • @BoratSagdiyev I don't; that was a response to a comment that has been deleted now. – erickson May 07 '14 at 20:04

15 Answers15

49

An official proposal has been made to allow static methods in interfaces in Java 7. This proposal is being made under Project Coin.

My personal opinion is that it's a great idea. There is no technical difficulty in implementation, and it's a very logical, reasonable thing to do. There are several proposals in Project Coin that I hope will never become part of the Java language, but this is one that could clean up a lot of APIs. For example, the Collections class has static methods for manipulating any List implementation; those could be included in the List interface.


Update: In the Java Posse Podcast #234, Joe D'arcy mentioned the proposal briefly, saying that it was "complex" and probably would not make it in under Project Coin.


Update: While they didn't make it into Project Coin for Java 7, Java 8 does support static functions in interfaces.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • 5
    Looks like static methods in interfaces are [coming in Java 8](http://hg.openjdk.java.net/lambda/lambda/langtools/rev/67030038d40b). – Bas Leijdekkers Feb 13 '13 at 09:04
  • 2
    The new Java 8 `java.util.function.Function` have declared a static method `identity`. so yes in Java 8 we have static methods in interfaces. – Earth Engine Jul 25 '13 at 11:54
41

I'm going to go with my pet theory with this one, which is that the lack of consistency in this case is a matter of convenience rather than design or necessity, since I've heard no convincing argument that it was either of those two.

Static fields are there (a) because they were there in JDK 1.0, and many dodgy decisions were made in JDK 1.0, and (b) static final fields in interfaces are the closest thing java had to constants at the time.

Static inner classes in interfaces were allowed because that's pure syntactic sugar - the inner class isn't actually anything to do with the parent class.

So static methods aren't allowed simply because there's no compelling reason to do so; consistency isn't sufficiently compelling to change the status quo.

Of course, this could be permitted in future JLS versions without breaking anything.

Pi Delport
  • 10,356
  • 3
  • 36
  • 50
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • 1
    I must admit I still don't understand why you find it surprising that static methods aren't allowed in interfaces. It might be a good idea if you explained why they should be allowed in the first place. No offense, I'm simply curious, I can't see why static methods should be part of interfaces... – Alexander Sep 25 '08 at 21:39
  • 3
    Simply for consistency, not for design reasons. If you're going to allow statics of any kind in interfaces, then you should allow any statics, not just certain types. – skaffman Sep 26 '08 at 07:47
  • 1
    Let's forget the syntax for a second. I think Sun decided they needed a way to define constants (e.g., enums, flags) in interfaces and the closest thing that was there in Java at the time was static final fields. As discussed, it's not perfect (not really constants, no symmetry), but... – Alexander Sep 28 '08 at 13:24
  • 8
    A static method on an interface would be a great place to invoke the java.util.ServiceLoader to get a concrete instance. I view the "new" operator as a static method of the class to which it is applied. Look at its reflective counterpart, a method on Class that doesn't require an instance. – erickson Oct 01 '08 at 21:39
  • Consistency with what? static in fields could be used in two ways. A) class attributes and B) constants. Class attributes are not allowed in interfaces, for they just define a contract to follow and not an state or impl. Constanst are neither state or impl, just, well contants. Hence consistent. – OscarRyz Jan 01 '09 at 00:24
  • *future JLS versions without breaking anything* they break reflection badly, though - as of now no one expects (and checks) for static methods while walking the declared methods of an interface -- so it wont happen. I think there was an official RFE, must look for. – bestsss Jul 23 '12 at 20:49
  • @bestsss: Suppose that Java standards body were to decide that declaring a static method within an interface would be synonymous with declaring a static inner class with some particular name that had never been used for anything, and anything in source code that looked like an invocation of a method on an interface would check whether an inner class existed with an appropriate name. If interfaces are already allowed to have static inner classes, would such a feature break even reflection-based code? It would seem especially handy if one could declare static methods... – supercat Sep 20 '12 at 22:03
  • ...with a special syntax to indicate that if `foo` is an variable of interface type `bar` which has no method `boz`, `foo.boz(9)` would look to see if the interface contains a static class `StaticClassesCA37BF13B5` [random hex number, so I doubt any class by that name already exists anywhere in the universe] with a method `boz(bar, int)`. Such a thing could allow consumers of an interface to benefit from utility methods without every implementation having to provide a boilerplate implementation. – supercat Sep 20 '12 at 22:09
15

There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). (EDIT:Since that last sentence confused some people, calling MyClass.staticMethod() executes precisely the implementation of staticMethod on MyClass, which if MyClass is an interface cannot exist!) If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.

More importantly, static methods are never overridden, and if you try to do:

MyInterface var = new MyImplementingClass();
var.staticMethod();

the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.

You can of course always remove the static keyword from the method. Everything will work fine. You may have to suppress some warnings if it is called from an instance method.

To answer some of the comments below, the reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.

DJClayworth
  • 26,349
  • 9
  • 53
  • 79
  • 2
    "They cannot be executed by the normal call MyInterface.staticMethod()." Why not? I thought this was the point of the question - why is this not allowed? – Dave L. Sep 24 '08 at 21:47
  • 16
    I agree, isn't this the point of the question? This answer is a tautology--"You can't do it because it doesn't work!" – erickson Oct 01 '08 at 17:39
  • Agreed, good answer, but to another question ;-) – Guillaume Dec 11 '08 at 14:45
  • 4
    "it doesn't have code by definition". I think the point is, that we'd like it to. In static methods. (https://docs.google.com/Doc?docid=dfkwr6vq_30dtg2z9d8&hl=en) – Brian Duff Aug 11 '10 at 01:50
  • They can't be executed by "MyInterface.staticMethod()" because that syntax always calls the implementation on the class specified. Interfaces can't have an implementation by definition. I imagined that would be obvious, or I would have explained it. – DJClayworth Dec 06 '10 at 14:21
  • 1
    So as I understand it, the commenters here are saying they think Java should allow implementations of methods on interfaces. Feel free to write your own languages. The point of this answer is to illustrate how given certain fundamental design decisions ("interfaces don't have code") these semantics arise naturally. – DJClayworth Dec 06 '10 at 14:27
  • @DJClayworth, I don't understand this part, "Everything will work fine. You may have to suppress some warnings if it is called from an instance method." I don't understand the scenario at all, especially since I tried calling the non-static interface method from an instance method of the implementer and got no warnings. Please help me understand. – batbrat Feb 25 '14 at 07:34
  • 3
    No need to write our own language. Java provided the answer to this question: There is no reason not to have static methods in interfaces, and Java 8 now has them. – Dave L. Dec 29 '14 at 21:07
6

The purpose of interfaces is to define a contract without providing an implementation. Therefore, you can't have static methods, because they'd have to have an implementation already in the interface since you can't override static methods. As to fields, only static final fields are allowed, which are, essentially, constants (in 1.5+ you can also have enums in interfaces). The constants are there to help define the interface without magic numbers.

BTW, there's no need to explicitly specify static final modifiers for fields in interfaces, because only static final fields are allowed.

Alexander
  • 9,302
  • 2
  • 26
  • 22
  • 4
    First, static finals are *not* constants, that's an interview-failing answer. Secondly none of this answers why you can have static fields and inner classes in an interface, but not methods. – skaffman Sep 25 '08 at 06:45
  • Sure, you can modifiy the values of static final fields if you use complex types, but you still can't reassign them. Sure, you can bypass the idea that they are intended to be used as a replacement for magic numbers, but that's because of Java's syntax only. – Alexander Sep 25 '08 at 07:58
  • Please read my answer again if you think I haven't answered why static methods aren't allowed. – Alexander Sep 25 '08 at 07:59
  • I haven't mentioned static inner classes because you dismissed the already in your question. – Alexander Sep 25 '08 at 08:00
  • 3
    The question asks why static fields and inner classes are acceptable in interfaces. This doesn't answer that question. – Zach Langley Jan 01 '09 at 00:29
  • 1
    I guess all of you so called religious fanatics are scratching your heads now with your statements when static methods in interfaces is exactly what has been introduced in Java 8? Don't say never, please! Don't ever make an absolute statement, or pretend that you know the ins and outs of what a developer needs or what is useful. Shit like this makes me upset. Seriously! And if you ask me, they should even allow instance method implementations in interfaces as well, so we can all start multiple inherit shit... blog.loxal.net/2013/05/java-8-default-interface.html – mjs Jul 17 '13 at 09:59
  • Why do you say that "static finals are not constants", skaffman? How would you indicate a field is a constant? – Peter vdL Sep 12 '14 at 16:48
6

This is an old thread , but this is something very important question for all. Since i noticed this today only so i am trying to explain it in cleaner way:

The main purpose of interface is to provide something that is unimplementable, so if they provide

static methods to be allowed

then you can call that method using interfaceName.staticMethodName(), but this is unimplemented method and contains nothing. So it is useless to allow static methods. Therefore they do not provide this at all.

static fields are allowed

because fields are not implementable, by implementable i mean you can not perform any logical operation in field, you can do operation on field. So you are not changing behavior of field that is why they are allowed.

Inner classes are allowed

Inner classes are allowed because after compilation different class file of the Inner class is created say InterfaceName$InnerClassName.class , so basically you are providing implementation in different entity all together but not in interface. So implementation in Inner classes is provided.

I hope this would help.

3

Prior to Java 5, a common usage for static fields was:

interface HtmlConstants {
    static String OPEN = "<";
    static String SLASH_OPEN = "</";
    static String CLOSE = ">";
    static String SLASH_CLOSE = " />";
    static String HTML = "html";
    static String BODY = "body";
    ...
}

public class HtmlBuilder implements HtmlConstants { // implements ?!?
    public String buildHtml() {
       StringBuffer sb = new StringBuffer();
       sb.append(OPEN).append(HTML).append(CLOSE);
       sb.append(OPEN).append(BODY).append(CLOSE);
       ...
       sb.append(SLASH_OPEN).append(BODY).append(CLOSE);
       sb.append(SLASH_OPEN).append(HTML).append(CLOSE);
       return sb.toString();
    }
}

This meant HtmlBuilder would not have to qualify each constant, so it could use OPEN instead of HtmlConstants.OPEN

Using implements in this way is ultimately confusing.

Now with Java 5, we have the import static syntax to achieve the same effect:

private final class HtmlConstants {
    ...
    private HtmlConstants() { /* empty */ }
}

import static HtmlConstants.*;
public class HtmlBuilder { // no longer uses implements
    ...
}
toolkit
  • 49,809
  • 17
  • 109
  • 135
  • I agree, you can declare static final fields in an Interface, but you should not do it ;-) – Guillaume Dec 11 '08 at 14:47
  • 1
    Guil, I disagree. You should declare constants in an interface only if they're declared as valid return types or inputs for the contract specified in the interface. Yes, declaring an interface just for constants is undesired, but if the constants relate to the contract, then by all means do it. – MetroidFan2002 Dec 11 '08 at 16:25
  • 4
    This doesn't address the OP's question about static methods. – bradheintz Mar 10 '09 at 21:05
3

Actually sometimes there are reasons someone can benefit from static methods. They can be used as factory methods for the classes that implement the interface. For example that's the reason we have Collection interface and the Collections class in openjdk now. So there are workarounds as always - provide another class with a private constructor which will serve as a "namespace" for the static methods.

3

There is no real reason for not having static methods in interfaces except: the Java language designers did not want it like that. From a technical standpoint it would make sense to allow them. After all an abstract class can have them as well. I assume but did not test it, that you can "hand craft" byte code where the interface has a static method and it should imho work with no problems to call the method and/or to use the interface as usually.

Angel O'Sphere
  • 2,642
  • 20
  • 18
2

I often wonder why static methods at all? They do have their uses, but package/namespace level methods would probably cover 80 of what static methods are used for.

Vasil
  • 36,468
  • 26
  • 90
  • 114
1

Two main reasons spring to mind:

  1. Static methods in Java cannot be overridden by subclasses, and this is a much bigger deal for methods than static fields. In practice, I've never even wanted to override a field in a subclass, but I override methods all the time. So having static methods prevents a class implementing the interface from supplying its own implementation of that method, which largely defeats the purpose of using an interface.

  2. Interfaces aren't supposed to have code; that's what abstract classes are for. The whole point of an interface is to let you talk about possibly-unrelated objects which happen to all have a certain set of methods. Actually providing an implementation of those methods is outside the bounds of what interfaces are intended to be.

Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
  • 2
    1. Classes can have static methods, and you can't override those, either. They're not there for over-riding, they're essentially just scoped functions. – skaffman Sep 24 '08 at 19:28
  • 2. I agree that interfaces should npt have code, but they already do - static fields initialisers can have have code and logic of their own. So the dam has already burst, I just want consistency. – skaffman Sep 24 '08 at 19:29
  • What do you mean when you say static field initializers can have code and logic of their own? You mean that they can call a method that can be fully resolved statically to initialize themselves? This isn't code. And static init blocks aren't allowed in interface. – cynicalman Sep 24 '08 at 19:40
1

Static methods are tied to a class. In Java, an interface is not technically a class, it is a type, but not a class (hence, the keyword implements, and interfaces do not extend Object). Because interfaces are not classes, they cannot have static methods, because there is no actual class to attach to.

You may call InterfaceName.class to get the Class Object corresponding to the interface, but the Class class specifically states that it represents classes and interfaces in a Java application. However, the interface itself is not treated as a class, and hence you cannot attach a static method.

MetroidFan2002
  • 29,217
  • 16
  • 62
  • 80
  • Interfaces *do* extend Object. – Angel O'Sphere May 16 '11 at 15:27
  • 2
    No, they don't. By definition, if an interface extended Object, it would be a class, because only classes may extend Object. Anything that implements an interface does by definition extend Object, because the only things that can implement interfaces are classes, and every class in Java implicitly extends Object. JLS: "While every class is an extension of class Object, there is no single interface of which all interfaces are extensions." (http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html) – MetroidFan2002 May 18 '11 at 23:48
  • Fixed link: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.1.3 – dolmen Feb 01 '13 at 09:44
  • Interfaces are most certainly define a class (Type, as you called them). The main difference is they act like abstract classes in they cannot be instantiated, and do not extend anything. – Mark Renouf Mar 13 '17 at 21:40
0

Only static final fields may be declared in an interface (much like methods, which are public even if you don't include the "public" keyword, static fields are "final" with or without the keyword).

These are only values, and will be copied literally wherever they are used at compile time, so you never actually "call" static fields at runtime. Having a static method would not have the same semantics, since it would involve calling an interface without an implementation, which Java does not allow.

cynicalman
  • 5,861
  • 3
  • 30
  • 30
  • A static method is effectively "final" also, since it cannot be overriden. Hotspot copies static methods of classes all the time. – skaffman Sep 24 '08 at 19:31
  • The difference here is that there is no way to copy a function pointer around in pure Java, so if you have a call to MyInterface.STATIC_FINAL_STTRING in your code, it will literally be replaced by the value. Code would still need to be executed through an interface with no implementation. – cynicalman Sep 24 '08 at 19:43
  • 1
    Sorry, edit timed out. From a technical standpoint nothing speaks against static methods in interfaces. I would bet you could hand craft bytecode and it would work. You dont need a "function pointer". Static methods are invoked via _invokestatic_ with a pointer into the constant pool holding classname and megthod name. Also the answer above regarding "copying" of "constants" is WRONG. Ofc static final fields are not copied by the compiler. A _getstatic_ bytecode is used. Otherwise if you change the Java file with the constant and recompile it, all other class files had the wrong value. – Angel O'Sphere May 13 '11 at 11:56
0

The reason is that all methods defined in an interface are abstract whether or not you explicitly declare that modifier. An abstract static method is not an allowable combination of modifiers since static methods are not able to be overridden.

As to why interfaces allow static fields. I have a feeling that should be considered a "feature". The only possibility I can think of would be to group constants that implementations of the interface would be interested in.

I agree that consistency would have been a better approach. No static members should be allowed in an interface.

laz
  • 28,320
  • 5
  • 53
  • 50
0

I believe that static methods can be accessed without creating an object and the interface does not allow creating an object as to restrict the programmers from using the interface methods directly rather than from its implemented class. But if you define a static method in an interface, you can access it directly without its implementation. Thus static methods are not allowed in interfaces. I don't think that consistency should be a concern.

0

Java 1.8 interface static method is visible to interface methods only, if we remove the methodSta1() method from the InterfaceExample class, we won’t be able to use it for the InterfaceExample object. However like other static methods, we can use interface static methods using class name. For example, a valid statement will be: exp1.methodSta1();

So after looking below example we can say : 1) Java interface static method is part of interface, we can’t use it for implementation class objects.

2) Java interface static methods are good for providing utility methods, for example null check, collection sorting ,log etc.

3) Java interface static method helps us in providing security by not allowing implementation classes (InterfaceExample) to override them.

4) We can’t define interface static method for Object class methods, we will get compiler error as “This static method cannot hide the instance method from Object”. This is because it’s not allowed in java, since Object is the base class for all the classes and we can’t have one class level static method and another instance method with same signature.

5) We can use java interface static methods to remove utility classes such as Collections and move all of it’s static methods to the corresponding interface, that would be easy to find and use.

public class InterfaceExample implements exp1 {

    @Override
    public void method() {
        System.out.println("From method()");
    }

    public static void main(String[] args) {
        new InterfaceExample().method2();
        InterfaceExample.methodSta2();      //  <---------------------------    would not compile
        // methodSta1();                        //  <---------------------------    would not compile
        exp1.methodSta1();
    }

    static void methodSta2() {          //          <-- it compile successfully but it can't be overridden in child classes
        System.out.println("========= InterfaceExample :: from methodSta2() ======");
    }
}


interface exp1 {

    void method();
    //protected void method1();         //          <--      error
    //private void method2();           //          <--      error
    //static void methodSta1();         //          <--      error it require body in java 1.8

    static void methodSta1() {          //          <-- it compile successfully but it can't be overridden in child classes
        System.out.println("========= exp1:: from methodSta1() ======");
    }

    static void methodSta2() {          //          <-- it compile successfully but it can't be overridden in child classes
        System.out.println("========= exp1:: from methodSta2() ======");
    }

    default void method2() { System.out.println("---  exp1:: from method2() ---");}
    //synchronized default void method3() { System.out.println("---");}             // <-- Illegal modifier for the interface method method3; only public, abstract, default, static 
                                                                                // and strictfp are permitted
    //final default void method3() { System.out.println("---");} //             <--      error
}
Ashish Sharma
  • 574
  • 7
  • 18
  • `interface static method helps us in providing security by not allowing implementation classes to override them` If this is a concern of yours, make the method `final` to prevent overrides. – Henrik Aasted Sørensen Oct 10 '17 at 11:30
  • We could not define final method in interface and we want to define final method in each class having same behavior then that could produce lot of duplicate code. Basically static methods in interface add one more functionality :- we could add similar type of action and can behave differently in implementing classes. Also we can keep all common type of actions/behaviors in interface in the name of static methods if we think that will help us saving some code in current inheritance design. – Ashish Sharma Oct 11 '17 at 03:27