Java 如果Enum声明没有';我没有递归部分
请看 和 供一般性讨论。在这里,我想了解如果枚举类被定义为Java 如果Enum声明没有';我没有递归部分,java,generics,enums,Java,Generics,Enums,请看 和 供一般性讨论。在这里,我想了解如果枚举类被定义为 public class Enum<E extends Enum> 公共类枚举 我使用以下代码来测试我的想法: interface MyComparable<T> { int myCompare(T o); } class MyEnum<E extends MyEnum> implements MyComparable<E> { public int myCompa
public class Enum<E extends Enum>
公共类枚举
我使用以下代码来测试我的想法:
interface MyComparable<T> {
int myCompare(T o);
}
class MyEnum<E extends MyEnum> implements MyComparable<E> {
public int myCompare(E o) { return -1; }
}
class FirstEnum extends MyEnum<FirstEnum> {}
class SecondEnum extends MyEnum<SecondEnum> {}
接口MyComparable{
国际货币基金组织;
}
类MyEnum实现MyComparable{
公共int myCompare(EO){return-1;}
}
类FirstEnum扩展MyEnum{}
类SecondEnum扩展MyEnum{}
在这种情况下,我无法找到任何好处
另外,事实是我不被允许这样做
class ThirdEnum extends MyEnum<SecondEnum> {}
类ThirdEnum扩展了MyEnum{}
使用递归定义MyEnum时为a) 不相关,因为对于真正的枚举,您不允许这样做,因为您自己无法扩展枚举
b) 不正确-请在编译器中尝试,并确保它实际上能够编译而不存在任何错误 PPS。我越来越倾向于相信这里的正确答案是“如果删除递归部分,一切都不会改变”——但我就是不相信这一点。考虑
Enum.compareTo(E other)
即:
- 需要使用E而不是enum,这样您就不会试图将一个enum值与来自不同enum的值进行比较
- 需要能够通过
上声明的enum
方法获取枚举的序数值ordinal()
这只是我想到的第一个。。。我相信还有很多其他的。基本上,这是一种说法,“你不应该试图将所有枚举视为彼此等价……枚举本身是一个封闭集,但所有枚举都共享某些属性。”首先,它会抱怨使用原始类型,但你可以这样做:
public class Enum<E extends Enum<?>>
public class Enum如果没有泛型类型参数,则无法为已创建的枚举的特定子类型扩展compariable
您可以忽略这一点,创建自己的MyEnum类型,其行为基本相同,但不受不同MyEnum不可比较的限制:
public abstract class MyEnum implements Comparable<MyEnum>
{
private final int ordinal;
protected MyEnum ( int ordinal )
{
this.ordinal = ordinal;
}
public int ordinal ()
{
return ordinal ;
}
public int compareTo ( MyEnum other )
{
return ordinal - other.ordinal; // ignore overflow for now
}
public boolean equals (Object other) {
return ordinal == ((MyEnum)other).ordinal;
}
public int hashCode () {
return ordinal;
}
}
在这种情况下,如果不重写equals
,您将失去x.comparesTo(y)=0
意味着x.equals(y)
;如果您确实重写了equals,那么在某些情况下,x.equals(y)
并不意味着x==y
(对于其他值对象),而对于Java枚举,两个相等测试都会产生相同的结果。我认为这样做的一个令人信服的原因是它使MyEnum类中的代码更加类型安全
`X extends Enum<Y>`
考虑到递归部分使这样的事情成为可能:
class MyEnum<E extends MyEnum<E>> {
private Thing<E> util1() { return someObject }
private void util2(E e) {}
public int method(E o) {
Thing<E> thingy = o.util1();
// You can call the util1 method on o and get a type safe return element.
E o1 = // I don't care how you get a parametrized E object.
o.util2(o1);
// You can call the util2 method with a typesafe parameter.
}
}
classmyenum{
私有对象util1(){return someObject}
私有无效util2(E){}
公共整数方法(EO){
thingy=o.util1();
//您可以在o上调用util1方法并获得类型安全的返回元素。
eo1=//我不在乎如何得到参数化的E对象。
o、 util2(o1);
//可以使用类型安全参数调用util2方法。
}
}
简而言之,这种递归性允许您将类型安全方法放在Enum类中,您可以对任何E元素调用该类,并且这些调用将是类型安全的。`X扩展Enum`
`X extends Enum<Y>`
这是违法的。这是相关的。编译器可以使用enum
具有特殊规则,但如果可能,为什么不使用完美的类型声明呢?compareTo-请参阅我的qn。这样一来,它就完全按照你说的那样工作了。不带任何递归。ordinal也没有问题-你能提供一些破坏/不安全的代码吗?@atamur:我没有注意到你示例中的原始类型位(你在问的前五分钟内编辑了吗?也许我只是误读了它)。老实说,您需要一个原始类型immediate这一事实让我感到紧张……如果序号是原因,那么class enum原始类型听起来很有趣——但是如果您真的尝试了,javac不会发出任何原始警告。请在qn中查看我的ps。有两点原因与此无关。我正在使用eclipse,它给出了关于原始类型的警告(更不用说sun已经说过我们不应该再使用原始类型了)。也许javac需要某种激活的选项来抱怨这一点?同样,ps的第二点对于我的示例是不正确的,如果我将类设置为public class MyEnum
,它就不会编译。关于第一点,我认为它可能能够生成.class文件,这样它就具有方法签名,就像类是这样编写的(通过使用非标准编译器)即使javac不允许您编译public enum FirstEnum extensed MyEnum
或类似的东西。请参见最后一段的添加。至于原始类型,我将查看jls(javac保持沉默应该有原因),我不完全相信在这种情况下,它仍然被视为原始类型用法。请注意,o.util2(this)
不会编译,因为它被认为是MyEnum而不是E。您可以添加第二个参数eo1
并调用o.util2(o1)
但效果相同:它将使用E extends MyEnum
编译,但不能使用E extends MyEnum
编译,谢谢!如果删除递归,该代码确实会被标记为不安全!您知道jdk中该功能的实际使用情况吗?Enum类本身将该方法用于getDeclaringClass
方法(该方法依次用于compareTo
方法)。此答案不适用于Enum
,因为类Enum
没有返回Thing
的实例方法。恐怕您不理解我的qn。如果你看一下我的代码,MyEnum使用的是泛型,而不是递归位。
`X extends Enum<Y>`