【问题标题】:Return generic class which extends Enum and implements and Interface-Java返回扩展 Enum 并实现和 Interface-Java 的泛型类
【发布时间】:2015-12-09 18:02:08
【问题描述】:

我有一个界面:

public MyInterface {};

很少有枚举实现MyInterface

public enum MyFirstEnums implements MyInterface{};

在另一个类中,我需要一个方法来返回 Class 对象,这样 该类应该像MyFirstEnums,它扩展了枚举并实现了MyInterface。

方法的返回类型应该是:<E extends Enum<?> & MyInterface>,应该允许返回 MyFirstEnums.class 和类似的枚举

我试着这样做:

public <E extends Enum<?> & MyInterface> Class<E> getClazz(){
    return MyFirstEnums.class;
}

但这给了我错误:

Type mismatch: cannot convert from Class<MyFirstEnums> to Class<E> 

我在这里错过了什么?

在其他地方,我尝试了一种将此类类型作为参数的方法,并且效果很好:

public <E extends Enum<?> MyInterface> void doSomething(Class<E> myClazz){};
 //it rightly checks the type of myClazz while calling this method

【问题讨论】:

    标签: java generics enums


    【解决方案1】:

    你不能只返回MyFirstEnum 的类对象。您的方法被声明为返回一个对应于枚举并实现MyInterface 的类对象,但它可能是MyFirstEnum 以外的枚举,也符合此条件。想象一下你有另一个枚举:

    public enum MySecondEnum implements MyInterface { }
    

    你也可以这样做:

    Class<MySecondEnum> clazz = getClazz();
    

    编译器从clazz 的目标返回类型推断类型参数(E 推断为MySecondEnum)。在这种情况下,显然很可能会发生运行时异常。例如,当您尝试从返回的类中实例化一个对象时,您会得到一个java.lang.InstantiationException

    请注意,您的方法实际上并没有使用类型参数,那么为什么首先要使用泛型?

    如果您想要一种“通用”方式为实现接口的每个枚举返回类对象,您可以执行以下操作:

    abstract class EnumProvider<E extends Enum<?> & MyInterface> {
        ...
        public abstract Class<E> getClazz();
    }
    
    
    class MyFirstEnumProvider extends EnumProvider<MyFirstEnums> {
        ...
        @Override
        public Class<MyFirstEnums> getClazz() {
            return MyFirstEnums.class;
        }
    
    }
    

    【讨论】:

    • 我确实有其他实现 MyInterface 的此类枚举,这就是我的目标:允许返回所有此类类型的枚举。我怎样才能做到这一点?方法没有使用类型参数,但它使用它作为返回类型。这没有意义吗?
    • @Anmol 这显然对编译器没有意义。如果你只想返回MyFirstEnums.class,返回类型应该只是Class&lt;MyFirstEnums&gt;。我已经用可能的通用解决方案更新了答案。
    • 谢谢!这根据 OP 起作用。在 OP 中没有提到它,但我试图在另一个枚举类中定义这种方法,其中每个枚举实例应返回不同的类,该类扩展 Enum 并实现 MyInterface。我想我做了一些复杂的事情,以一种更简单的方式来实现我的目的。
    【解决方案2】:

    我会尝试一些回应:

    您想定义一个方法,该方法返回一些未完全定义但尊重的类类型:扩展 Enum 和 MyInterface。

    而且你的类没有传递给方法。

    我怀疑这是不可能或不安全的。

    我愿意:

    1 传递一个我想要的类作为参数

    2 逆向测试:我在里面测试 Class 是否扩展了 Enum & MyInterface 和 MyFirstEnum.class 以及 MyFirstEnum.class 是否扩展了类

    3 当然 Class result=MyFirstEnum.class;可以更复杂,以前不为人所知...

    这可以编译(因为测试是在运行时进行的)但我不知道它是否可以帮助你。

    public  <E> Class<E> getClazz(Class< E> _return_class) throws Exception
        {
        Class result=MyFirstEnum.class;
    
        if (MyInterface.class.isAssignableFrom(_return_class) )
            if (Enum.class.isAssignableFrom(_return_class))
                if (_return_class.isAssignableFrom(result))
    
            return (Class<E>) result;
    
     throw new Exception("Bad Class");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多