【发布时间】:2018-05-05 22:32:50
【问题描述】:
从 Java 8 开始,您可以在接口中实现默认或静态方法,如下所示
public interface DbValuesEnumIface<ID, T extends Enum<T>> {
T fromId(ID id);
ID getId();
static String getDescriptionKey(){
return "this is a test";
}
}
我想用具有签名的静态方法声明上述内容,该签名使用实现类定义的边界,因为该方法的实现应该对所有人都相同,唯一不同的是声明的泛型,如下所示:
public interface DbValuesEnumIface<ID, T extends Enum<T>> {
public static T fromId(ID id) {
if (id == null) {
return null;
}
for (T en : T.values()) {
if (en.getId().equals(id)) {
return en;
}
}
}
ID getId();
String getDescriptionKey();
}
...
public enum Statuses implements DbValuesEnumIface<Integer,Statuses>
因为 T 和 ID 不是静态的并且不能从静态上下文中引用而中断。
那么,如何修改以上内容才能成功编译,如果不可能,如何实现以上内容以达到预期目的,同时避免实现类中的代码重复。
【问题讨论】:
-
不完全确定这个问题是否特别需要与 Java 8 和接口有关。对于尝试使用为
class? 定义的类型参数的static方法,相同的规则通常也适用于类? -
@CKing 在接口中拥有静态方法的能力是 Java8 特有的,并且手头的问题是通过使用具有泛型的接口而发生的。所以相应地添加了标签。 ``` 中断是因为 T 和 ID 不是静态的,并且不能从静态上下文中引用 ``` 如果 DbValuesEnumIface 是一个我只是在子类中扩展的类,但如果这就是你的意思的话,可能仍然会出现。作为示例中的接口,它可能存在一些独特的问题,因此这就是添加此信息的原因。
-
没有扭结。类或接口。泛型类型参数遵循相同的规则。静态是静态的,实例是实例。此外,
T.values其中T是类或方法类型参数(不管static)违反了语言的语法规则。当问题与语言无关时,请发布一个特别考虑语言规则的示例?更重要的是,谈论编译错误的问题肯定会消除与直接问题 IMO 无关的所有编译错误。 -
其实有一个接口具体的区别。对于普通类,你可以像
SubClass.method(…)一样调用SuperClass的static方法,提高了可以使用继承参数化(例如class SubClass extends SuperClass<SpecificType>)的期望,令人失望的是它不起作用。相反,static接口的方法一开始就没有被继承。所以你不能做Statuses.fromId(…),而只能做DbValuesEnumIface.fromId(…),这显然需要明确提示Statuses是要搜索的类。 -
@Holger “接口的静态方法一开始就没有被继承” 没错。虽然您可以使用默认方法(可能会导致相同的问题)并且 Java 可以解决冲突,但静态方法的处理方式不同。
标签: java generics interface static java-8