154

The topic says the most of it - what is the reason for the fact that static methods can't be declared in an interface?

public interface ITest {
    public static String test();
}

The code above gives me the following error (in Eclipse, at least): "Illegal modifier for the interface method ITest.test(); only public & abstract are permitted".

skaffman
  • 398,947
  • 96
  • 818
  • 769
Henrik Paul
  • 66,919
  • 31
  • 85
  • 96
  • 2
    Please unaccept Espo's answer, as it is flawed. An interface has a class-file that could contain the implementation of a static method (if the Java-designer would allow this), so there is no problem in resolving the implementation of the static method. It works exactly as with other static classes. – Mnementh Sep 26 '08 at 08:51
  • i kind of agree with the answer given by "erickson" http://stackoverflow.com/questions/512877/why-cant-i-define-a-static-method-in-a-java-interface – Maverick Nov 11 '13 at 11:59
  • 9
    This will be available in Java 8 btw. – m0skit0 Dec 29 '13 at 14:11
  • @m0skit0 Do you have any link about that? Sounds cool. – Vadorequest Feb 03 '14 at 21:19
  • 1
    @Vadorequest GIYF but anyway, [check here](http://java.dzone.com/articles/introduction-default-methods) – m0skit0 Feb 05 '14 at 11:47
  • Yeah of course I could have find it ;) But when you said something like this it's always better to give the link! Thanks. – Vadorequest Feb 05 '14 at 12:35
  • 2
    Links from official documentation : [Java SE tutorial](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html#static) & [Java Language Specification 9.2](https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.2) – LoganMzz Apr 22 '15 at 08:31

14 Answers14

86

There are a few issues at play here. The first is the issue of declaring a static method without defining it. This is the difference between

public interface Foo {
  public static int bar();
}

and

public interface Foo {
  public static int bar() {
    ...
  }
}

The first is impossible for the reasons that Espo mentions: you don't know which implementing class is the correct definition.

Java could allow the latter; and in fact, starting in Java 8, it does!

Community
  • 1
  • 1
James A. Rosen
  • 64,193
  • 61
  • 179
  • 261
  • 2
    Yes - it's idealogical not technical. The reason I would like it is. that one can have a static "implementation" method in an interface that only references other "interface" methods in the interface that can be easily re-used by implementing classes. But one can declare a static *class* in an interface so one could have such things reside there like MyInterface.Impl.doIt(MyInterface i, Object[] args) { ... } – peterk Jun 21 '13 at 15:02
  • 9
    Since Java 8, you can define `static` methods in an `interface`. The methods must be `public`. – Olivier Grégoire Jun 25 '14 at 12:46
  • 5
    @OlivierGrégoire ...and they are not inherited, which is key. – William F. Jameson Aug 06 '14 at 21:12
  • 1
    Good answer, though "approximately equivalent" ROFLMAO xD I would have put it more like "somewhat resembles". – Timo May 18 '15 at 12:51
44

The reason why you can't have a static method in an interface lies in the way Java resolves static references. Java will not bother looking for an instance of a class when attempting to execute a static method. This is because static methods are not instance dependent and hence can be executed straight from the class file. Given that all methods in an interface are abstract, the VM would have to look for a particular implementation of the interface in order to find the code behind the static method so that it could be executed. This then contradicts how static method resolution works and would introduce an inconsistency into the language.

Espo
  • 41,399
  • 21
  • 132
  • 159
  • 3
    This explanation doesn't explain the problem. Every interface have it's own class-file, it could contain the static-method. So no lookup for a particular implementation would be needed. – Mnementh Sep 26 '08 at 08:38
  • Not every interface type in Java is within it's own file, nor should it be according to JLS. Additionally JLS doesn't stipulate that classes have to be always stored withing a file system, quite the contrary. – Vlad Gudim Feb 06 '09 at 12:22
  • 4
    @Totophil: Interfaces must not be in a single java-file, but it will have an own class-file after compiling. That's what I wrote. – Mnementh Jan 07 '11 at 16:00
18

I'll answer your question with an example. Suppose we had a Math class with a static method add. You would call this method like so:

Math.add(2, 3);

If Math were an interface instead of a class, it could not have any defined functions. As such, saying something like Math.add(2, 3) makes no sense.

Kyle Cronin
  • 77,653
  • 43
  • 148
  • 164
11

The reason lies in the design-principle, that java does not allow multiple inheritance. The problem with multiple inheritance can be illustrated by the following example:

public class A {
   public method x() {...}
}
public class B {
   public method x() {...}
}
public class C extends A, B { ... }

Now what happens if you call C.x()? Will be A.x() or B.x() executed? Every language with multiple inheritance has to solve this problem.

Interfaces allow in Java some sort of restricted multiple inheritance. To avoid the problem above, they are not allowed to have methods. If we look at the same problem with interfaces and static methods:

public interface A {
   public static method x() {...}
}
public interface B {
   public static method x() {...}
}
public class C implements A, B { ... }

Same problem here, what happen if you call C.x()?

Mnementh
  • 50,487
  • 48
  • 148
  • 202
  • Any reason for the downvote? A explaining comment would be nice. – Mnementh Jan 07 '11 at 16:01
  • i am not the downvoter, but isn't this valid for non-static methods too? – nawfal Oct 05 '12 at 15:36
  • OK, here are two different possibilities. A method could be implemented or only declared. I understood, that the static method has to be implemented. In that meaning I encounter the problem presented in my answer. If you don't do that, you run into the problem Espo described - and that I didn't understand because I assumed the static method would be implemented. You also cannot declare a static abstract method for this reason, try it out, the compiler will complain. – Mnementh Oct 05 '12 at 20:42
  • Ok, forget the implementation part. the question is why cant we declare. yes the compiler will complain and why is that is the question. to which I dont think you have answered. – nawfal Oct 05 '12 at 20:53
  • 1
    How would the situation there be any worse than having interface `A` contain `int x(int z);` and interface `B` contain `string x(int x);`? What is the meaning of `x(3)` in interface C? – supercat Feb 01 '13 at 08:26
  • I am not sure i agree with the exact wording, but the answer does make sense in explaining why static methods in Interface should not be allowed. – Stefan Mar 21 '13 at 17:00
  • But static fields are allowed. I could define an `A.x` and a `B.x` on your interfaces. And in that case trying to refer to (an ambiguous) `C.x` causes a compile-time error. Couldn't the same thing be done for static methods? (Is that the plan in Java 8?) – Partly Cloudy Aug 23 '13 at 23:41
7

Static methods are not instance methods. There's no instance context, therefore to implement it from the interface makes little sense.

Ryan Farley
  • 11,315
  • 4
  • 46
  • 43
6

Now Java8 allows us to define even Static Methods in Interface.

interface X {
    static void foo() {
       System.out.println("foo");
    }
}

class Y implements X {
    //...
}

public class Z {
   public static void main(String[] args) {
      X.foo();
      // Y.foo(); // won't compile because foo() is a Static Method of X and not Y
   }
}

Note: Methods in Interface are still public abstract by default if we don't explicitly use the keywords default/static to make them Default methods and Static methods resp.

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
Anandaraja_Srinivasan
  • 568
  • 1
  • 10
  • 25
4

There's a very nice and concise answer to your question here. (It struck me as such a nicely straightforward way of explaining it that I want to link it from here.)

Community
  • 1
  • 1
Zarkonnen
  • 22,200
  • 14
  • 65
  • 81
3

It seems the static method in the interface might be supported in Java 8, well, my solution is just define them in the inner class.

interface Foo {
    // ...
    class fn {
        public static void func1(...) {
            // ...
        }
    }
}

The same technique can also be used in annotations:

public @interface Foo {
    String value();

    class fn {
        public static String getValue(Object obj) {
            Foo foo = obj.getClass().getAnnotation(Foo.class);
            return foo == null ? null : foo.value();
        }
    }
}

The inner class should always be accessed in the form of Interface.fn... instead of Class.fn..., then, you can get rid of ambiguous problem.

Lenik
  • 13,946
  • 17
  • 75
  • 103
2

An interface is used for polymorphism, which applies to Objects, not types. Therefore (as already noted) it makes no sense to have an static interface member.

Rob Cooper
  • 28,567
  • 26
  • 103
  • 142
1

Java 8 Had changed the world you can have static methods in interface but it forces you to provide implementation for that.

public interface StaticMethodInterface {
public static int testStaticMethod() {
    return 0;
}

/**
 * Illegal combination of modifiers for the interface method
 * testStaticMethod; only one of abstract, default, or static permitted
 * 
 * @param i
 * @return
 */
// public static abstract int testStaticMethod(float i);

default int testNonStaticMethod() {
    return 1;
}

/**
 * Without implementation.
 * 
 * @param i
 * @return
 */
int testNonStaticMethod(float i);

}

Kumar Abhishek
  • 3,004
  • 33
  • 29
0

Illegal combination of modifiers : static and abstract

If a member of a class is declared as static, it can be used with its class name which is confined to that class, without creating an object.

If a member of a class is declared as abstract, you need to declare the class as abstract and you need to provide the implementation of the abstract member in its inherited class (Sub-Class).

You need to provide an implementation to the abstract member of a class in sub-class where you are going to change the behaviour of static method, also declared as abstract which is a confined to the base class, which is not correct

Sankar
  • 162
  • 2
  • 13
  • How does this answer the question? The OP asked about interface while you wrote about class. – Lucky Sep 19 '16 at 13:16
0

Since static methods can not be inherited . So no use placing it in the interface. Interface is basically a contract which all its subscribers have to follow . Placing a static method in interface will force the subscribers to implement it . which now becomes contradictory to the fact that static methods can not be inherited .

ip_x
  • 172
  • 2
  • 6
0

With Java 8, interfaces can now have static methods.

For example, Comparator has a static naturalOrder() method.

The requirement that interfaces cannot have implementations has also been relaxed. Interfaces can now declare "default" method implementations, which are like normal implementations with one exception: if you inherit both a default implementation from an interface and a normal implementation from a superclass, the superclass's implementation will always take priority.

Ishara
  • 11
  • 3
-2

Perhaps a code example would help, I'm going to use C#, but you should be able to follow along.

Lets pretend we have an interface called IPayable

public interface IPayable
{
    public Pay(double amount);
}

Now, we have two concrete classes that implement this interface:

public class BusinessAccount : IPayable
{
    public void Pay(double amount)
    {
        //Logic
    }
}

public class CustomerAccount : IPayable
{
    public void Pay(double amount)
    {
        //Logic
    }
}

Now, lets pretend we have a collection of various accounts, to do this we will use a generic list of the type IPayable

List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());

Now, we want to pay $50.00 to all those accounts:

foreach (IPayable account in accountsToPay)
{
    account.Pay(50.00);
}

So now you see how interfaces are incredibly useful.

They are used on instantiated objects only. Not on static classes.

If you had made pay static, when looping through the IPayable's in accountsToPay there would be no way to figure out if it should call pay on BusinessAcount or CustomerAccount.

FlySwat
  • 172,459
  • 74
  • 246
  • 311
  • Just because static methods make no sense in THIS example, does not mean that they don't make sense in ANY example. In your example if the IPayable interface had static method "IncrementPayables" that kept track of how many payables were added, this would be a real use case. Of course, one could always use an abstract class, but that's not what you addressed. Your example in itself does not undermine static methods in interfaces. – Cruncher Aug 27 '13 at 15:10