将类文字返回为交集类型

Tib*_*ssy 9 java generics enums

我有两个实现一些通用接口的枚举,我想从该方法返回类文字.但是我无法正确指定交集类型.请参阅下面的说明问题的代码示例.

public class GenericsTest {    
  interface Iface {   
  }

  enum E1 implements Iface {    
  }

  enum E2 implements Iface {    
  }

  <E extends Enum<E> & Iface> Class<E> getEnum1() {
    return E1.class;  //ERROR incompatible types: java.lang.Class<GenericsTest.E1> cannot be converted to java.lang.Class<E>
  }

  Class<? extends Enum<?>> getEnum3() {
    return E1.class;  //OK
  }

  Class<? extends Iface> getEnum4() {
    return E1.class;  //OK
  }

  <E extends Enum<E> & Iface> void enumParam(Class<E> p) {
    enumParam(E1.class);  //OK
  }

}
Run Code Online (Sandbox Code Playgroud)

#getEnum1方法不编译.有趣的是,它作为参数值起作用#enumParam.如何指定交集类型以便能够从方法返回类文字?

Tam*_*dus 2

该方法getEnum1无法编译的原因与此相同:

public <E> E foo() {
    return "bar"; // Compile time error: Incompatible types E and String
}
Run Code Online (Sandbox Code Playgroud)

看?仅仅因为类型参数最终E可能是字符串,并不意味着它String. 人们可以将此函数称为Integer i = x.<Integer>foo();,因此返回字符串在这里没有意义。

getEnum1是完全一样的。类型参数E可以选择类型E1(这里命名非常糟糕),但这并不意味着E1始终与E. 考虑E2 e2 = x.<E2>getEnum1();。您可能想知道为什么编译器在尝试使用错误的类型参数调用它时不只是警告错误。问题是,E2满足类型约束,所以没有理由在那里显示错误。

那么如何才能让你的代码正常工作呢?

最简单(也可能是唯一)的方法就是去掉泛型:

Class<E1> getEnum1() {
  return E1.class;
}
Run Code Online (Sandbox Code Playgroud)

如果您不想E1在这里公开具体类型,那么您就不走运了。您所能做的就是将通用功能提取到接口中,然后返回该类型。