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?
Edit: Clarification why is this not a duplicate:
- Question "Why can't static methods be abstract in Java" deals with abstract classes not interfaces and thus is not related to my question. - Question "Why can't I define a static method in a Java interface?" was, even linked as related question by myself. However this question was originally posted before Java 8 introduced support for static methods in interfaces as a feature. It aimed at an explanation why it is not possible to define static methods in a Java interface, which is no longer true since the release of Java 8. While the answer has been updated with some background information according the new static interface member support in Java 8 it does not explain how the feature is to be used. My question boils down to how this static interface method feature can be properly implemented which is not being addressed in the answer to the question marked as duplicate. In addition I'm trying to understand why the example code I provided behaves the way it does, which is only partially being addressed in the answer to the question marked as duplicate. Finally I'm not talking about "Constructor interfaces" here. So while the question "Why can't static methods be abstract in Java" is related to my question it most certainly is not a duplicate.