具有通用签名的接口中的静态方法 [英] Static Method in Interface with Generic signature

查看:107
本文介绍了具有通用签名的接口中的静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Java 8开始,您可以在Interfaces中实现以下默认或静态方法

As of Java 8 you can have default or static methods implemented in Interfaces as the below

public interface DbValuesEnumIface<ID, T extends Enum<T>> {
   T fromId(ID id);

   ID getId();
   static String getDescriptionKey(){
      return "this is a test";
   }
}

我想用静态方法声明以上内容,该方法的签名使用实现类定义的边界,因为该方法的实现对所有人来说应该是相同的,唯一不同的应该是所声明的泛型,例如:

I would like to declare the above with the static method having a signature that uses bounds defined by the implementing classes since the method's implementation should be the same for all,with the only thing different should be the generics declared, as such:

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不是静态的,并且不能从静态上下文中引用.

which breaks because T and ID are not static and cant be referenced from a static context.

因此,应如何修改以上内容以成功编译,如果不可行,应如何实现以上内容以实现所需的目的,同时避免在实现类中重复代码.

So, how should the above be modified to compile successfully and if thats not possible, how the above should be implemented to achieve the desired purpose while avoiding code duplication within implementing classes .

推荐答案

由于static方法与描述实例化参数的类的类型参数之间没有关系,因此必须制作static方法通用.棘手的部分是使声明正确地描述所有需要的约束.并且正如此答案所述,您需要使用Class参数,否则,实现没有机会获得掌握实际的类型参数:

Since there is no relationship between static methods and the class’ type parameters, which describe how instances are parameterized, you have to make the static method generic on its own. The tricky part is to get the declarations right to describe all needed constraints. And as this answer already explained, you need to a a Class parameter, as otherwise, the implementation has no chance to get hands on the actual type arguments:

public interface DbValuesEnumIface<ID, T extends Enum<T>> {

   public static
   <ID, T extends Enum<T>&DbValuesEnumIface<ID,T>> T fromId(ID id, Class<T> type) {
        if (id == null) {
            return null;
        }
        for (T en : type.getEnumConstants()) {
            if (en.getId().equals(id)) {
                return en;
            }
        }
        throw new NoSuchElementException();
    }

    ID getId();

    String getDescriptionKey();
}

请注意,static方法的类型参数独立于类的类型参数.为了清楚起见,您可以考虑给它们使用不同的名称.

Note that the type parameters of the static method are independent from the class’ type parameter. You may consider giving them different names for clarity.

因此,现在,以您提供的enum Statuses implements DbValuesEnumIface<Integer,Statuses>示例为例,您可以使用Statuses status = DbValuesEnumIface.fromId(42, Statuses.class);

So now, given you enum Statuses implements DbValuesEnumIface<Integer,Statuses> example, you can use the method like Statuses status = DbValuesEnumIface.fromId(42, Statuses.class);

请注意,对于default方法,可以以

Note that for default methods, it is possible to access the actual type, as a method providing the enum type will be provided by the implementation. You only have to declare the presence of the method within the interface:

public interface DbValuesEnumIface<ID, T extends Enum<T>&DbValuesEnumIface<ID,T>> {

    public default T fromId(ID id) {
        if (id == null) {
            return null;
        }
        for (T en : getDeclaringClass().getEnumConstants()) {
            if (en.getId().equals(id)) {
                return en;
            }
        }
        throw new NoSuchElementException();
    }
    Class<T> getDeclaringClass();//no needed to implement it, inherited by java.lang.Enum
    ID getId();
    String getDescriptionKey();
}

但是,明显的缺点是您需要一个目标实例来调用该方法,即Statuses status = Statuses.SOME_CONSTANT.fromId(42);

However, the obvious disadvantage is that you need a target instance to invoke the method, i.e. Statuses status = Statuses.SOME_CONSTANT.fromId(42);

这篇关于具有通用签名的接口中的静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆