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

24

565

EDIT: As of Java 8, static methods are now allowed in interfaces.

Here's the example:

public interface IXMLizable<T>
{
  static T newInstanceFromXML(Element e);
  Element toXMLElement();
}

Of course this won't work. But why not?

One of the possible issues would be, what happens when you call:

IXMLizable.newInstanceFromXML(e);

In this case, I think it should just call an empty method (i.e. {}). All subclasses would be forced to implement the static method, so they'd all be fine when calling the static method. So why isn't this possible?

EDIT: I guess I'm looking for answer that's deeper than "because that's the way Java is".

Is there a particular technological reason why static methods can't be overwritten? That is, why did the designers of Java decide to make instance methods overrideable but not static methods?

EDIT: The problem with my design is I'm trying to use interfaces to enforce a coding convention.

That is, the goal of the interface is twofold:

  1. I want the IXMLizable interface to allow me to convert classes that implement it to XML elements (using polymorphism, works fine).

  2. If someone wants to make a new instance of a class that implements the IXMLizable interface, they will always know that there will be a newInstanceFromXML(Element e) static constructor.

Is there any other way to ensure this, other than just putting a comment in the interface?

Angloindian answered 4/2, 2009 at 19:21 Comment(10)
You don't need to clutter method (and field) definitions with public in interfaces, btw.Jamnis
Hmm, seems to be a duplicate of #22317. Hadn't seen that before.Foldaway
Could you provide some code how would you like to use static interface methods?Amah
also dupe of #129767Colonel
@Erickson,Could you illustrate with an example where Usage of static method fails in interfaceDalia
This will be possible in Java 8: docs.oracle.com/javase/tutorial/java/IandI/…Ibby
@Ibby Yes, but it doesn't do what the OP wants.Campbell
Possible duplicate of Why no static methods in Interfaces, but static fields and inner classes OK? [pre-Java8]Narva
@JohnMercier's question is closed now. This is now the true threadStricklin
This is possible in Java 8 - check my answer below: https://mcmap.net/q/23320/-why-can-39-t-i-define-a-static-method-in-a-java-interfaceOleaginous
A
575

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.

Alrick answered 4/2, 2009 at 19:56 Comment(28)
Good call on Project Coin. mail.openjdk.java.net/pipermail/coin-dev/2009-March/000117.htmlFoldaway
Could reason for #1 be multiple inheritance? Since we can inherit from multiple interfaces, if two interfaces contained the same static method signature and then a class implemented them both and called that method, then things could become complicated in a way that Java language creators wanted to avoid by disallowing multiple class inheritance in the first place. Same argument could obviously be made for interface not allowing any method definition in them at all.Discursive
By same argument, even field constants should be disallowed in interfaces, but maybe handling them for multiple inheritance is not as complicated.Discursive
@Discursive - No, static methods are resolved at compile time. The ambiguity can be handled the same way that it's handled with constants: with a compiler error. However, the proposal under Project Coin was rejected, citing some unforeseen difficulties. Not sure what they were, but I don't think it was along these lines.Alrick
@Erickson,Could you illustrate with an example where Usage of static method fails in interface.Dalia
@Deepak: Sorry, I'm not sure what you mean. This post is about defining static methods in an interface. Are you talking about assigning the result of a static method to a (constant) interface field?Alrick
I can't wait until they do. You can declare static fields already, so you can create your static functions wrapped in static objects as a hack.Fiftieth
Am I correct in understanding that Java 8 addresses point 1. but not 2. ? And btw the short answer to point 2 is "optimization" - because having static overridable methods in interfaces is a quite valid OO requirement (think of behavior common to all instances of each particular implementing class of an interface, which could be used as <T extends MyInterface> method(Class<T> cls){cls.staticMethod();//...}Cath
Yes, Java 8 doesn't change anything static method "override". I'm not following your example for how these would be used. But I wonder if Java 8 might actually help you out. I will need to read up on it, but I think there's a default method implementation mechanism that might address what you're getting at.Alrick
You've mention that class are static. In Java that might be true but it does not need to be the case. There is many language that adopt this position (Smalltalk for one of the pioneer). If you think of it there is many situation where you want a class to be dynamic. If class become an object that is a whole new world that offer to you and many DI framework almost become useless.Siebert
I think that the answer should be updated according to Java 8 so that you don't have to read other answers to know full pictureQuinonoid
@Quinonoid I made some changes. Is that what you meant?Alrick
yes. But now your 1 question is inconsistent with this :) you say "you can do X" and next line: "1. why you can't do X?". Maybe 1 point should disappear or be sth like following: "Why can't interfaces contain static methods up to Java 8?"Quinonoid
@Quinonoid No, question #1 is specifically about interfaces, while question #2 is about static methods generally.Alrick
no, you misunderstood. The contradiction I see is between post beginning (With Java 8, interfaces can have static methods) and first point (1. Why can't interfaces contain static methods). Now you can reread my last comment in this context. If you can, then what's the point of explaining why you can't. That's why I suggested simple reformulating of 1. point.Quinonoid
Does any of this discussion address that the Java 8 inclusion of static interfaces does not address the "enforcing a convention" concept that the OP wanted? Or did I misunderstand both this conversation and the OP? I would love a code enforcement version of static methods, even if it [grotesquely] required a new keyword. Something akin to interface ClassReset{musthave public static void RESET();}Minnieminnnie
@tgm1024 Yes, the section "Constructor 'interfaces'" explains why it doesn't make sense to try to invoke polymorphic behavior through a type known at compile time. How would you invoke RESET() on a given class? You'd write SomeClass.RESET(). So you don't need an interface to describe that API; its static. Interfaces are used when you don't know the concrete type at compile-time. That's never the case with a static method.Alrick
@erickson, I read that, but it doesn't apply to what I wrote----I'm not looking for polymorphic behavior at all. I'm looking for code enforcement (note: Not contract enforcement in the polymorphic sense). I want to make sure that there is a public static RESET(). Nothing polymorphic about this: It's a static method----a member of a class. Hence the reason I suggested that I could even put up with a new, albeit grotesque, keyword. There ought to be a way to say "This class must have these static methods defined". Perhaps an @MustHavethen if it doesn't fit within the language proper.Minnieminnnie
@tgm1024 Yes, I completely understood what you are looking for. My reference to polymorphism was because interfaces only describe the operations of an instance. I know that's a tautological response to a question about why interfaces can't have static methods, so there's another half to my response: static interface methods make no sense and would be useless. Interfaces are useful for instances because code is written with those interfaces as reference types, i.e., you write code that calls run() on a Runnable instance. You can't invoke Resettable.RESET(). You'd need the runtime type.Alrick
@erickson, I suppose what I'm objecting to is that this should have been clear from what I wrote originally, and while you seem to have understood it, it seemed to me given the response that you didn't. The enforcement of a coding convention was one of the goals in the OP's OP. In my case, I'm looking for a (static something) coding requirement to be enforced within a class; certainly nothing polymorphic in nature. @ThouShaltHaveThisThing public static int HOOZIT and @ThouShaltHaveThisThing public static int WAZZIT(int bla), to belabor the point. Thanks for the response anyway though.Minnieminnnie
@tgm1024 Yes, I got that too, but I removed that part because my comment was too long and I hoped that by explaining what interfaces are good for, the implication that what they are not good for would be sufficiently clear. But, to put too fine a point on it: Interfaces were never intended to enforce coding conventions.Alrick
"Construction is part of the implementation, not the interface. Any code that works successfully with the interface doesn't care about the constructor." -- That is clearly not true. In other languages (e.g. Swift), I can create new instances of T without knowing T statically, because I promise in an interface that a certain constructor (or static method) will exist at runtime. The fact that generation is impossible to specify in Java does not mean it's not a meaningful thing to do.Venireman
"Any code that cares about the constructor needs to know the concrete type anyway, and the interface can be ignored." -- with that logic, interfaces can always be ignored, no? Why is caring about constructors/generators different from caring about methods?Venireman
@Venireman Good points in your first comment. Of course, Java supports other creational patterns to decouple instantiation from implementation. I might need to re-word some of that. In your Swift example, is T a generic type parameter of the code that is performing the instantiation? Of course, Java's type erasure doesn't make that easy, but there are some tricks that can be used to achieve something similar. I don't really understand your second comment though. It doesn't follow that the type of an injected object can be ignored.Alrick
@Alrick Yes, T can be a type parameter; see e.g. here. Similarly, you can require static properties and functions of a Swift class or struct. Not that the Swift type system is perfect -- there are serious shortcomings around generics -- but this part is very useful. I don't see any conceptual reason against it in Java; it's purely a compiler feature. Requiring constructors and static members by themselves, that is; erasure of generics is another issue.Venireman
@Venireman most of this can be solved in Java by defining an additional factory interface. When its sole factory method matches an implementation’s constructor, it can be implemented as simple as ImplementationType::new, or via ImplementationType::factoryMethodName. The use of this pattern only requires methods to take another parameter for the factory when required. That’s a bit more verbose than factory methods mandated by an interface, on the other hand, it offers much more flexibility, e.g. the opportunity to define, implement, and use other factories than declared in the interface.Westernize
@Alrick How else are we supposed to enforce that the method signature be the same? For example, if I want to refactor/rename the method I want it to apply to all of them easily. It would be easy to do if inheriting static interface methods were possible. Otherwise they all have to be changed separately.Pennell
@Pennell Instead of treating those functions as global, static methods, make them instance methods of different classes that implement a common interface. The description you gave of what you want is that of an interface; use an interface.Alrick
J
54

This was already asked and answered, here

To duplicate my answer:

There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). 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.

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.

While you can say that this amounts to "because Java does it that way", in reality the decision is a logical consequence of other design decisions, also made for very good reason.

Jiggerypokery answered 4/2, 2009 at 19:50 Comment(6)
If you use <T extends MyInterface> as a generic type parameter, it would be nice to guarantee via interface that T can .doSomething().Sampling
While I understand the arguments, I agree with @Chris_Betti (even for non-generic types): it'd be nice that the code structure ensures that some classes implements a specific static API. Maybe it is possible using a different concept...Barquisimeto
@Juh_, .....or a new keyword if absolutely required. I believe static is a crummy term in languages anyway, and has been stretched too far as is. So having it by itself is already sketchy. See my example above #513377 {shrug}.Minnieminnnie
This seems untrue: "There is never a point to declaring a static method in an interface." If I have a collection of classes that, without being instantiated, could offer me some information but I'd need a common interface to put this static class-level information in (i.e. an interface with an overridable static method) then that's a valid use. Think reflection++, where you could capture meta-information about class properties without hacking around with attributes, reflection, etc.Henigman
There is never a point to declaring a static method in an interface. Sometimes static methods in interface make sense, because they enforce more functional approach. Static methods in interfaces can't mutate static state of interface, because there's no state in interface at all.Tradein
"There is never a point to declaring a static method in an interface." This is not true: imagine your system has a default class resolver. If it detects that you implement ContainerInjectionInterce::create(Container $container) method, than it will create the object with this function for instance.Thomasthomasa
T
41

With the advent of Java 8 it is possible now to write default and static methods in interface. docs.oracle/staticMethod

For example:

public interface Arithmetic {

    public int add(int a, int b);

    public static int multiply(int a, int b) {
        return a * b;
    }
}
public class ArithmaticImplementation implements Arithmetic {

    @Override
    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int result = Arithmetic.multiply(2, 3);
        System.out.println(result);
    }
}

Result : 6

TIP : Calling an static interface method doesn't require to be implemented by any class. Surely, this happens because the same rules for static methods in superclasses applies for static methods on interfaces.

Treed answered 26/11, 2014 at 17:13 Comment(1)
This is a perfect example of this question.Ecuador
D
38

UPDATE: In Java 8, static methods were added to interfaces.

public interface IXMLizable {

    /**
     * Converts the implementing object to an XML element.
     *
     * @return An Element representation of the implementing object.
     */
    public Element toXMLElement();

    /**
     * Static factory method to create a new class instance implementing IXMLizable from an XML element.
     *
     * @param e The XML Element from which to create the IXMLizable instance.
     * @return An instance of a class that implements IXMLizable, initialized from the given XML element.
     */
    public static IXMLizable create(Element e) {
        return new MyIXMLizable(e);
    }
}

Normally, this is done using a Factory pattern

public interface IXMLizable {
  public Element toXMLElement();
}


public interface IXMLizableFactory<T extends IXMLizable> {
  public T newInstanceFromXML(Element e);
}

public interface IXMLizable {
  public Element toXMLElement();
}
Digastric answered 13/2, 2009 at 21:37 Comment(9)
+1 a factory pattern sounds like the solution to the problem. (though not to the question)Tendril
Can somebody tell me what is the meaning of putting<T extends IXMLizable> here .I am new to java.What does it do?Kinetics
@NuwanHarshakumaraPiyarathna T must be a class extending IXMLizable. Look into Java generics for a better understanding of what this meansMagdalen
So each class needs a corresponding factory class? That seems very verbose. It seems like I could accomplish the same thing by defining it in IXMLizable instead, and calling (new IXMLizable()).newInstanceFromXML(...) as a hacky workaround to the fact that static methods can't be inherited. What advantages does the factory pattern offer over that?Pennell
@Pennell in Java 8, static methods were added to interfacesDigastric
@PeterLawrey Yes, but those static methods aren't inherited and have nothing to do with each other between superclass/subclass, so your original solution is still needed... unless I'm missing somethingPennell
@pete, you are right, though. If you need to subclasses of factory instances, you have a fairly complex design. In most cases, there is only one implementation of the interface (though it might have more later), and a lot of the time, there are only a few.Digastric
I am having multiple classes implement IXMLizableFactory. Correct me if I misunderstood, but it seemed implied in your original answer, that "IXMLizableFactory" could be implemented by multiple classes, which offers a way to enforce the coding pattern OP was describing, as each class has a different way to become instantiated via XML, but they all have the ability to somehow be instantiated via XML. What would be the use of an interface which is only implemented by 1 class?Pennell
@Pennell In future, there could be other implementations; it could be altered via a System property or other means.Digastric
F
26

Because static methods cannot be overridden in subclasses, and hence they cannot be abstract. And all methods in an interface are, de facto, abstract.

Foldaway answered 4/2, 2009 at 19:22 Comment(2)
You could always force each type to implement any static interface methods. Typeclasses, anyone?Herzl
Step outside yourself and answer the question: Why can't a static methods be overridden? If static methods could be overridden, what would it look like? What could you do with them? This answer is basically "You can't because you can't."Alrick
O
14

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

Actually you can in Java 8.

As per Java doc:

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

In Java 8 an interface can have default methods and static methods. This makes it easier for us to organize helper methods in our libraries. We can keep static methods specific to an interface in the same interface rather than in a separate class.

Example of default method:

list.sort(ordering);

instead of

Collections.sort(list, ordering);

Example of static method (from doc itself):

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));
    }    
}
Oleaginous answered 1/7, 2015 at 13:33 Comment(1)
great to know that these Util classes can be replaced with static methods in the interface itself.Steradian
F
7

Interfaces are concerned with polymorphism which is inherently tied to object instances, not classes. Therefore static doesn't make sense in the context of an interface.

Foredeck answered 4/2, 2009 at 19:28 Comment(1)
Clear, concise logic. Well put.Gipsy
E
6

First, all language decisions are decisions made by the language creators. There is nothing in the world of software engineering or language defining or compiler / interpreter writing which says that a static method cannot be part of an interface. I've created a couple of languages and written compilers for them -- it's all just sitting down and defining meaningful semantics. I'd argue that the semantics of a static method in an interface are remarkably clear -- even if the compiler has to defer resolution of the method to run-time.

Secondly, that we use static methods at all means there is a valid reason for having an interface pattern which includes static methods -- I can't speak for any of you, but I use static methods on a regular basis.

The most likely correct answer is that there was no perceived need, at the time the language was defined, for static methods in interfaces. Java has grown a lot over the years and this is an item that has apparently gained some interest. That it was looked at for Java 7 indicates that its risen to a level of interest that might result in a language change. I, for one, will be happy when I no longer have to instantiate an object just so I can call my non-static getter method to access a static variable in a subclass instance ...

Edmonds answered 5/7, 2011 at 22:54 Comment(0)
G
5
  • "Is there a particular reason that static methods cannot be overridden".

Let me re-word that question for your by filling in the definitions.

  • "Is there a particular reason that methods resolved at compile time cannot be resolved at runtime."

Or, to put in more completely, If I want to call a method without an instance, but knowing the class, how can I have it resolved based upon the instance that I don't have.

Grainy answered 4/2, 2009 at 21:16 Comment(0)
M
4

Static methods aren't virtual like instance methods so I suppose the Java designers decided they didn't want them in interfaces.

But you can put classes containing static methods inside interfaces. You could try that!

public interface Test {
    static class Inner {
        public static Object get() {
            return 0;
        }
    }
}
Magee answered 4/2, 2009 at 19:59 Comment(0)
E
4

Commenting EDIT: As of Java 8, static methods are now allowed in interfaces.

It is right, static methods since Java 8 are allowed in interfaces, but your example still won't work. You cannot just define a static method: you have to implement it or you will obtain a compilation error.

Exotoxin answered 15/6, 2016 at 10:29 Comment(0)
F
3

Several answers have discussed the problems with the concept of overridable static methods. However sometimes you come across a pattern where it seems like that's just what you want to use.

For example, I work with an object-relational layer that has value objects, but also has commands for manipulating the value objects. For various reasons, each value object class has to define some static methods that let the framework find the command instance. For example, to create a Person you'd do:

cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();

and to load a Person by ID you'd do

cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();

This is fairly convenient, however it has its problems; notably the existence of the static methods can not be enforced in the interface. An overridable static method in the interface would be exactly what we'd need, if only it could work somehow.

EJBs solve this problem by having a Home interface; each object knows how to find its Home and the Home contains the "static" methods. This way the "static" methods can be overridden as needed, and you don't clutter up the normal (it's called "Remote") interface with methods that don't apply to an instance of your bean. Just make the normal interface specify a "getHome()" method. Return an instance of the Home object (which could be a singleton, I suppose) and the caller can perform operations that affect all Person objects.

Fabi answered 4/2, 2009 at 20:40 Comment(0)
H
1

Well, without generics, static interfaces are useless because all static method calls are resolved at compile time. So, there's no real use for them.

With generics, they have use -- with or without a default implementation. Obviously there would need to be overriding and so on. However, my guess is that such usage wasn't very OO (as the other answers point out obtusely) and hence wasn't considered worth the effort they'd require to implement usefully.

Herzl answered 4/2, 2009 at 19:27 Comment(2)
What do generics have to do with this? A static method on an interface would still be unexecutable.Jiggerypokery
First, that'd be an implementation decision. But I'm guessing he doesn't want to call static methods on an interface (he could just use a class). But instead wants to have something sorta like a typeclass or whatnot over type parameters. In fact, his latest edit shows this even more clearly.Herzl
T
1

An interface can never be dereferenced statically, e.g. ISomething.member. An interface is always dereferenced via a variable that refers to an instance of a subclass of the interface. Thus, an interface reference can never know which subclass it refers to without an instance of its subclass.

Thus the closest approximation to a static method in an interface would be a non-static method that ignores "this", i.e. does not access any non-static members of the instance. At the low-level abstraction, every non-static method (after lookup in any vtable) is really just a function with class scope that takes "this" as an implicit formal parameter. See Scala's singleton object and interoperability with Java as evidence of that concept. And thus every static method is a function with class scope that does not take a "this" parameter. Thus normally a static method can be called statically, but as previously stated, an interface has no implementation (is abstract).

Thus to get closest approximation to a static method in an interface, is to use a non-static method, then don't access any of the non-static instance members. There would be no possible performance benefit any other way, because there is no way to statically link (at compile-time) a ISomething.member(). The only benefit I see of a static method in an interface is that it would not input (i.e. ignore) an implicit "this" and thus disallow access to any of the non-static instance members. This would declare implicitly that the function that doesn't access "this", is immutate and not even readonly with respect to its containing class. But a declaration of "static" in an interface ISomething would also confuse people who tried to access it with ISomething.member() which would cause a compiler error. I suppose if the compiler error was sufficiently explanatory, it would be better than trying to educate people about using a non-static method to accomplish what they want (apparently mostly factory methods), as we are doing here (and has been repeated for 3 Q&A times on this site), so it is obviously an issue that is not intuitive for many people. I had to think about it for a while to get the correct understanding.

The way to get a mutable static field in an interface is use non-static getter and setter methods in an interface, to access that static field that in the subclass. Sidenote, apparently immutable statics can be declared in a Java interface with static final.

Taxidermy answered 14/2, 2011 at 12:22 Comment(0)
B
1
Why can't I define a static method in a Java interface?

All methods in an interface are explicitly abstract and hence you cannot define them as static because static methods cannot be abstract.

Burned answered 20/8, 2013 at 6:23 Comment(0)
L
0

Interfaces just provide a list of things a class will provide, not an actual implementation of those things, which is what your static item is.

If you want statics, use an abstract class and inherit it, otherwise, remove the static.

Hope that helps!

Langobardic answered 4/2, 2009 at 19:23 Comment(1)
Well, in theory, you could define an interface to include a static behaviour, that is, "implementations of this interface will have a static method foo() with this signature", and leave the implementation up to the specific class. I have encountered situations where this behaviour would be useful.Daughter
T
0

You can't define static methods in an interface because static methods belongs to a class not to an instance of class, and interfaces are not Classes. Read more here.

However, If you want you can do this:

public class A {
  public static void methodX() {
  }
}

public class B extends A {
  public static void methodX() {
  }
}

In this case what you have is two classes with 2 distinct static methods called methodX().

Taboo answered 4/2, 2009 at 19:35 Comment(0)
T
0

Suppose you could do it; consider this example:

interface Iface {
  public static void thisIsTheMethod();
}

class A implements Iface {

  public static void thisIsTheMethod(){
    system.out.print("I'm class A");
  }

}

class B extends Class A {

  public static void thisIsTheMethod(){
    System.out.print("I'm class B");
  } 
}

SomeClass {

  void doStuff(Iface face) {
    IFace.thisIsTheMethod();
    // now what would/could/should happen here.
  }

}
Tendril answered 13/2, 2009 at 16:4 Comment(4)
It would print "I'm class A". However, if you typed A.thisIsTheMethod() it would print "I'm class B".Angloindian
but oyr calling the methods on the interface how would you (or the compiler) know which method should be called? (rember there can be more classes dricetly implementing IfaceTendril
sorry, I meant to say: However, if you typed B.thisIsTheMethod() it would print "I'm class B".Angloindian
i said IFace.thisIsTHeMethod on purpose because therein lies the problem. it would not be possible to call it on the interface without undefined behavior (even though its declared on it)Tendril
P
0

Something that could be implemented is static interface (instead of static method in an interface). All classes implementing a given static interface should implement the corresponding static methods. You could get static interface SI from any Class clazz using

SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null

then you can call si.method(params). This would be useful (for factory design pattern for example) because you can get (or check the implementation of) SI static methods implementation from a compile time unknown class ! A dynamic dispatch is necessary and you can override the static methods (if not final) of a class by extending it (when called through the static interface). Obviously, these methods can only access static variables of their class.

Panties answered 3/10, 2013 at 14:43 Comment(0)
W
0

While I realize that Java 8 resolves this issue, I thought I'd chime in with a scenario I am currently working on (locked into using Java 7) where being able to specify static methods in an interface would be helpful.

I have several enum definitions where I've defined "id" and "displayName" fields along with helper methods evaluating the values for various reasons. Implementing an interface allows me to ensure that the getter methods are in place but not the static helper methods. Being an enum, there really isn't a clean way to offload the helper methods into an inherited abstract class or something of the like so the methods have to be defined in the enum itself. Also because it is an enum, you wouldn't ever be able to actually pass it as an instanced object and treat it as the interface type, but being able to require the existence of the static helper methods through an interface is what I like about it being supported in Java 8.

Here's code illustrating my point.

Interface definition:

public interface IGenericEnum <T extends Enum<T>> {
    String getId();
    String getDisplayName();
    //If I was using Java 8 static helper methods would go here
}

Example of one enum definition:

public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
    STANDARD ("Standard", "Standard Mode"),
    DEBUG ("Debug", "Debug Mode");

    String id;
    String displayName;

    //Getter methods
    public String getId() {
        return id;
    }

    public String getDisplayName() {
        return displayName;
    }

    //Constructor
    private ExecutionModeType(String id, String displayName) {
        this.id = id;
        this.displayName = displayName;
    }

    //Helper methods - not enforced by Interface
    public static boolean isValidId(String id) {
        return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
    }

    public static String printIdOptions(String delimiter){
        return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
    }

    public static String[] getIdArray(){
        return GenericEnumUtility.getIdArray(ExecutionModeType.class);
    }

    public static ExecutionModeType getById(String id) throws NoSuchObjectException {
        return GenericEnumUtility.getById(ExecutionModeType.class, id);
    }
}

Generic enum utility definition:

public class GenericEnumUtility {
    public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {       
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(enumOption.getId().equals(id)) {
                return true;
            }
        }

        return false;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
        String ret = "";
        delimiter = delimiter == null ? " " : delimiter;

        int i = 0;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(i == 0) {
                ret = enumOption.getId();
            } else {
                ret += delimiter + enumOption.getId();
            }           
            i++;
        }

        return ret;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
        List<String> idValues = new ArrayList<String>();

        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            idValues.add(enumOption.getId());
        }

        return idValues.toArray(new String[idValues.size()]);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
        id = id == null ? "" : id;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(id.equals(enumOption.getId())) {
                return (T)enumOption;
            }
        }

        throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
    }
}
Waxwing answered 20/5, 2015 at 19:10 Comment(0)
D
0

Let's suppose static methods were allowed in interfaces: * They would force all implementing classes to declare that method. * Interfaces would usually be used through objects, so the only effective methods on those would be the non-static ones. * Any class which knows a particular interface could invoke its static methods. Hence a implementing class' static method would be called underneath, but the invoker class does not know which. How to know it? It has no instantiation to guess that!

Interfaces were thought to be used when working with objects. This way, an object is instantiated from a particular class, so this last matter is solved. The invoking class need not know which particular class is because the instantiation may be done by a third class. So the invoking class knows only the interface.

If we want this to be extended to static methods, we should have the possibility to especify an implementing class before, then pass a reference to the invoking class. This could use the class through the static methods in the interface. But what is the differente between this reference and an object? We just need an object representing what it was the class. Now, the object represents the old class, and could implement a new interface including the old static methods - those are now non-static.

Metaclasses serve for this purpose. You may try the class Class of Java. But the problem is that Java is not flexible enough for this. You can not declare a method in the class object of an interface.

This is a meta issue - when you need to do ass

..blah blah

anyway you have an easy workaround - making the method non-static with the same logic. But then you would have to first create an object to call the method.

Decline answered 19/9, 2015 at 13:54 Comment(0)
A
0

To solve this : error: missing method body, or declare abstract static void main(String[] args);

interface I
{
    int x=20;
    void getValue();
    static void main(String[] args){};//Put curly braces 
}
class InterDemo implements I
{
    public void getValue()
    {
    System.out.println(x);
    }
    public static void main(String[] args)
    {
    InterDemo i=new InterDemo();
    i.getValue();   
    }

}

output : 20

Now we can use static method in interface

Accepter answered 29/10, 2017 at 9:10 Comment(1)
That's useless, though. Defining an static method on an interface does not enforce further definitions in classes which implements such interface. If you just remove the static method altogether from interface I, your code will compile and run anyway without problems. In other words, you are NOT overriding I interface's main method in InterDemo class, just creating a new method with the same signature.Nova
A
-3

I think Java does not have static interface methods, because you do not need them.

You may think you do, but... How would you use them? If you want to call them like

MyImplClass.myMethod()

then you do not need to declare it in the interface. If you want to call them like

myInstance.myMethod()

then it should not be static.

If you are actually going to use first way, but just want to enforce each implementation to have such static method, then it is really a coding convention, not a contract between instance that implements an interface and calling code.

Interfaces allow you to define contract between instance of class that implement the interface and calling code. And Java helps you to be sure that this contract is not violated, so you can rely on it without worrying which class implements this contract, just "someone who signed a contract" is enough. In case of static interfaces your code

MyImplClass.myMethod()

does not rely on the fact that each interface implementation has this method, so you do not need Java to help you to be sure with it.

Amah answered 4/2, 2009 at 20:35 Comment(0)
C
-5

What is the need of static method in interface, static methods are used basically when you don't have to create an instance of object whole idea of interface is to bring in OOP concepts with introduction of static method you're diverting from concept.

Cabral answered 4/4, 2013 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.