通用边界“Enum &Foo”和“Enum “
这两个(有效的)通用边界是:
<T extends Enum & MyInterface> <T extends Enum>
一样?
假设我有一个界面
interface MyInterface { void someMethod(); }
以及一些实现它的枚举:
enum MyEnumA implements MyInterface { A, B, C; public void someMethod() {} } enum MyEnumB implements MyInterface { X, Y, Z; public void someMethod() {} }
我想要求一个实现不仅使用MyInterface
而且还使用枚举。 “标准”方式是由一个交叉点绑定:
static class MyIntersectionClass<T extends Enum & MyInterface> { void use(T t) {} }
但我发现这也有效:
static class MyWildcardClass<T extends Enum> { void use(T t) {} }
有了上述,这个编译:
public static void main(String[] args) throws Exception { MyIntersectionClass a = new MyIntersectionClass(); a.use(MyEnumA.A); MyWildcardClass b = new MyWildcardClass(); b.use(MyEnumB.X); }
对于这两种情况,绑定对上面的工作和预期和要求都有效。
这两个界限之间是否存在差异,如果是这样,那么一个“比另一个”更“好”吗?
在这种特定情况下没有区别,因为Enumsforms类型参数实际上是自我类型。 这是因为我不能像以下那样从Enuminheritance:
class MyEnumA extends Enum {} class MyEnumB implements MyInterface {}
所以是的,从语义上看它们是相同的界限,但仅仅因为它是Enum。
正如其他人指出的那样,两种语法都达到了相同的界限 – 并且只是因为枚举的特殊情况,我们知道Enum
必须是立即扩展的enum
类型。 因此,在限制T
可以解决的问题时,没有区别。
T
实例的可能用法存在差异,但它可能是一个细微差别,它无关紧要。 请考虑以下语句在MyIntersectionClass.use
编译,但不在MyWildcardClass.use
编译:
T t2 = t.getDeclaringClass().newInstance();
只有这些将在后者编译:
MyInterface t2 = t.getDeclaringClass().newInstance(); Enum extends MyInterface> t3 = t.getDeclaringClass().newInstance();
由于第二个依赖于Java枚举实现为MyEnum extends Enum
的特殊事实,我更倾向于第一个,它不依赖于这样的假设并明确地陈述您的约束。
他们会做同样的事情,但我会说T extends Enum extends MyInterface>
T extends Enum extends MyInterface>
更标准,因此更好,只是因为它更常见和快速识别。 许多人甚至不了解仿制药的部分内容。
你也可以说他们的阅读略有不同。 T extends Enum
我会读作“一个也恰好是MyInterface的枚举”。 T extends Enum extends MyInterface>
T extends Enum extends MyInterface>
我会读作“实现MyInterface的枚举”。 所以在这个程度上,这是个人偏好的问题; 我更喜欢后者。