由于Java 8支持静态接口方法(根据this相关问题的答案),我一直在尝试编写如下代码:
示例1
public interface ITest<T extends Enum<T>>
{
static <T extends Enum<T>> String test();
}
通过javac
运行此命令会产生以下错误消息:
ITest.java:8: error: missing method body, or declare abstract
static <T extends Enum<T>> String test();
编译器错误消息让我感到困惑。据我所知,将关键字abstract添加到接口中定义的方法是多余的。将编译器推荐的定义更改为如下所示,只会将错误消息更改为在抽象类中声明成员静态时我期望看到的内容。
示例2
public interface ITest<T extends Enum<T>>
{
static abstract <T extends Enum<T>> String test();
}
编译器输出:
ITest.java:12: error: illegal combination of modifiers: abstract and static
static abstract <T extends Enum<T>> String test();
然而,更改接口以实现某些任意方法体使代码编译。
示例3
public interface ITest<T extends Enum<T>>
{
static <T extends Enum<T>> String test(T item) { return item.name(); }
}
令人惊讶的是,可以让类Test1
实现接口ITest
,而无需重新定义或覆盖方法test()
。但是,调用Test1.<T>test()
将导致编译器抱怨未解析的符号。在第二个类test()
中重新定义方法Test2
也可以,并且在这种情况下,实际上可以调用该方法。下面是一些用于说明问题的测试代码,取消注释main方法中接收“未解析符号”错误消息的第一个语句。
//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));
}
}
基于上述观察,我的结论是实现接口ITest绝对没有做任何事情。静态接口方法似乎总是需要一个(固定的?)默认实现。
正如标题中所述,我的问题是:是否可以在Java 8中定义类似于我的第一个示例的工作界面?如果这是不可能的,任何人都可以解释这里发生了什么?特别是事实上,只要未调用接口中定义的静态方法,示例1,2根本不进行编译而只编译3,这似乎没有意义。如果我可以按照示例3中的定义调用test()
,那么在实现test()
的类中ITest
是否可以覆盖,怎么做?
编辑:澄清为什么这不是重复:
- 问题“Why can't static methods be abstract in Java”处理抽象类而不是接口,因此与我的问题无关。 - 问题“Why can't I define a static method in a Java interface?”,甚至被我自己链接为相关的问题。但是,这个问题最初是在Java 8引入支持接口中的静态方法之前发布的。它旨在解释为什么不可能在Java接口中定义静态方法,自Java 8发布以来已经不再适用了。虽然根据Java中新的静态接口成员支持已经使用一些背景信息更新了答案。 8它没有解释如何使用该功能。我的问题归结为如何正确实现这种静态接口方法功能,这在标记为重复的问题的答案中没有得到解决。另外,我试图理解为什么我提供的示例代码的行为与它的行为方式有关,这只是在标记为重复的问题的答案中得到部分解决。最后,我不是在谈论“构造函数接口”。因此,虽然问题"Why can't static methods be abstract in Java"与我的问题有关,但肯定不是重复。