Why Can't I Define a Static Method in a Java Interface

Why can't I define a static method in a Java interface?

Java 8 permits static interface methods

With Java 8, interfaces can have static methods. They can also have concrete instance methods, but not instance fields.

There are really two questions here:

  1. Why, in the bad old days, couldn't interfaces contain static methods?
  2. Why can't static methods be overridden?

Static methods in interfaces

There was no strong technical reason why interfaces couldn't have had static methods in previous versions. This is summed up nicely by the poster of a duplicate question. Static interface methods were initially considered as a small language change, and then there was an official proposal to add them in Java 7, but it was later dropped due to unforeseen complications.

Finally, Java 8 introduced static interface methods, as well as override-able instance methods with a default implementation. They still can't have instance fields though. These features are part of the lambda expression support, and you can read more about them in Part H of JSR 335.

Overriding static methods

The answer to the second question is a little more complicated.

Static methods are resolvable at compile time. Dynamic dispatch makes sense for instance methods, where the compiler can't determine the concrete type of the object, and, thus, can't resolve the method to invoke. But invoking a static method requires a class, and since that class is known statically—at compile time—dynamic dispatch is unnecessary.

A little background on how instance methods work is necessary to understand what's going on here. I'm sure the actual implementation is quite different, but let me explain my notion of method dispatch, which models observed behavior accurately.

Pretend that each class has a hash table that maps method signatures (name and parameter types) to an actual chunk of code to implement the method. When the virtual machine attempts to invoke a method on an instance, it queries the object for its class and looks up the requested signature in the class's table. If a method body is found, it is invoked. Otherwise, the parent class of the class is obtained, and the lookup is repeated there. This proceeds until the method is found, or there are no more parent classes—which results in a NoSuchMethodError.

If a superclass and a subclass both have an entry in their tables for the same method signature, the sub class's version is encountered first, and the superclass's version is never used—this is an "override".

Now, suppose we skip the object instance and just start with a subclass. The resolution could proceed as above, giving you a sort of "overridable" static method. The resolution can all happen at compile-time, however, since the compiler is starting from a known class, rather than waiting until runtime to query an object of an unspecified type for its class. There is no point in "overriding" a static method since one can always specify the class that contains the desired version.


Constructor "interfaces"

Here's a little more material to address the recent edit to the question.

It sounds like you want to effectively mandate a constructor-like method for each implementation of IXMLizable. Forget about trying to enforce this with an interface for a minute, and pretend that you have some classes that meet this requirement. How would you use it?

class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}

Foo obj = Foo.newInstanceFromXML(e);

Since you have to explicitly name the concrete type Foo when "constructing" the new object, the compiler can verify that it does indeed have the necessary factory method. And if it doesn't, so what? If I can implement an IXMLizable that lacks the "constructor", and I create an instance and pass it to your code, it is an IXMLizable with all the necessary interface.

Construction is part of the implementation, not the interface. Any code that works successfully with the interface doesn't care about the constructor. Any code that cares about the constructor needs to know the concrete type anyway, and the interface can be ignored.

Why can't I declare static methods in an interface?

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!

Why can I define only default and static methods inside a java interface?

The reason we have default methods in interfaces is to allow the developers to add new methods to the interfaces without affecting the classes that implements these interfaces.
Here is link for complete article.

Why interface methods can't be static in class that implements the interface?

One could say: because @Override and static simply do not go together.

Keep in mind: polymorphism only works for non-static methods. static means that your method is "attached" to the containing class.

In other words: you know everything about static method invocations at compile time. But the process of determining which overridden method to invoke happens at runtime. These two concepts do not go together in Java.

Why can't I use from the static method of the implemented interface?

From the Java Language Specification,

A class C inherits from its direct superclass all concrete methods m
(both static and instance) of the superclass for which all of the
following are true:

  • [...]

A class C inherits from its direct superclass and direct
superinterfaces all abstract and default (§9.4) methods m for which
all of the following are true:

  • [...]

A class does not inherit static methods from its superinterfaces.

So that method is not inherited.

You can statically import the member

import static com.example.Interface1.printName;
...
printName();

or use it with the fully qualified type name

com.example.Interface1.printName();

or import the type to which printName belongs and invoke it with its short name

import static com.example.Interface1;
...
Interface1.printName();

Is putting static methods in interfaces a good practice?

Ultimately, this is a matter of style. However, if the only purpose of the helper class is to hold this method (and maybe a few similar ones), then you will be saving yourself one class definition by placing them in the interface:

As of Java 8, the restriction that interfaces cannot contain static methods was eliminated, so there is typically little reason to provide a noninstantiable companion class for an interface [Effective Java, 3rd edition].

Why would anyone define a static method in an interface in java 1.8?

Here I found nice explanation why we have static methods in interfaces:
http://www.baeldung.com/java-static-default-methods

The idea behind static interface methods is to provide a simple
mechanism that allows us to increase the degree of cohesion of a
design by putting together related methods in one single place without
having to create an object.

Pretty much the same can be done with abstract classes. The main
difference lies in the fact that abstract classes can have
constructors, state, and behavior.

Furthermore, static methods in interfaces make possible to group
related utility methods, without having to create artificial utility
classes that are simply placeholders for static methods.

So yes, the one of the examples is that instead of creating utility classes for some behavior, calculation related to your interface, you can choose to define related static methods directly in the interface. So you group functionality on the right place. You avoid additional classes

public interface Vehicle {

static int getHorsePower(int rpm, int torque) {
return (rpm * torque) / 5252;
}
}

Vehicle.getHorsePower(2500, 480));



public interface Cube {

static double volume(double a){
return a * a * a;
}

static double surface(double a){
return 6*a*a;
}
}

Why can't static methods be abstract in Java?

The abstract annotation to a method indicates that the method MUST be overriden in a subclass.

In Java, a static member (method or field) cannot be overridden by subclasses (this is not necessarily true in other object oriented languages, see SmallTalk.) A static member may be hidden, but that is fundamentally different than overridden.

Since static members cannot be overriden in a subclass, the abstract annotation cannot be applied to them.

As an aside - other languages do support static inheritance, just like instance inheritance. From a syntax perspective, those languages usually require the class name to be included in the statement. For example, in Java, assuming you are writing code in ClassA, these are equivalent statements (if methodA() is a static method, and there is no instance method with the same signature):

ClassA.methodA();

and

methodA();

In SmallTalk, the class name is not optional, so the syntax is (note that SmallTalk does not use the . to separate the "subject" and the "verb", but instead uses it as the statemend terminator):

ClassA methodA.

Because the class name is always required, the correct "version" of the method can always be determined by traversing the class hierarchy. For what it's worth, I do occasionally miss static inheritance, and was bitten by the lack of static inheritance in Java when I first started with it. Additionally, SmallTalk is duck-typed (and thus doesn't support program-by-contract.) Thus, it has no abstract modifier for class members.



Related Topics



Leave a reply



Submit