Since Java 8 supports static interface methods (according to the answer to this related question) I've been trying to write code that looks like this:
Example 1
public interface ITest<T extends Enum<T>> { static <T extends Enum<T>> String test(); }
Running this though javac yields the following error message:
ITest.java:8: error: missing method body, or declare abstract static <T extends Enum<T>> String test();
The compiler error message is already confusing me. As far as I understand adding the keyword abstract to a method defined in an interface is redundant. Changing the definition as recommended by the compiler to look like below just changes the error message, to what I'd expect to see when declaring a member static inside an abstract class.
Example 2
public interface ITest<T extends Enum<T>> { static abstract <T extends Enum<T>> String test(); }
The compiler outputs:
ITest.java:12: error: illegal combination of modifiers: abstract and static static abstract <T extends Enum<T>> String test();
However changing the interface to implement some arbitrary method body makes the code compile.
Example 3
public interface ITest<T extends Enum<T>> { static <T extends Enum<T>> String test(T item) { return item.name(); } }
Surprisingly is possible to have a class Test1 implementing the the interface ITest without redefining or overriding the method test(). However calling Test1.<T>test() will cause the compiler to complain about an unresolved symbol. Redefining the method test() in a 2nd class Test2 works as well, and in this case the method can actually be called. Here is some test code to illustrate the issue, uncomment the first statement in the main method to receive the "unresolved symbol" error message.
//ITest.java public interface ITest<T extends Enum<T>> { static <T extends Enum<T>> String test(T item) { return item.name(); } } //Test.java public class Test { public enum E { ONE, TWO, THREE } private static class Test1 implements ITest<E> {} private static class Test2 implements ITest<E> { static <T extends Enum<T>> String test(T item) { return item.name(); } } public static void main(String[] args) { //System.out.println(Test1.<E>test(E.ONE)); System.out.println(Test2.<E>test(E.ONE)); } }
Based on the above observations I do conclude that implementing the interface ITest does absolutely nothing. Also static interface methods seem to always require a (fixed?) default implementation.
As stated in the headline my question is: Can a working interface similar to my first example be defined in Java 8? If this is not possible can anyone explain what is going on here? Especially the fact that examples 1, 2 don't compile at all but 3 does compile as long as the static method defined in the interface is not invoked seems to make no sense. If I could call test() as defined in example 3, would test() be overridable in a class implementing ITest, how?