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>`