代码之家  ›  专栏  ›  技术社区  ›  ATorras

Java的Enum声明的含义是什么?

  •  5
  • ATorras  · 技术社区  · 16 年前

    在浏览Java的源代码时,我发现了以下声明:

    public abstract class Enum<E extends Enum<E>>
    

    应该如何解释?我被它困住了。。。

    非常感谢。

    7 回复  |  直到 16 年前
        1
  •  2
  •   Brian Agnew    16 年前

    你并不孤单。 Ken Arnold this

    或者,简单地说,说明同样的观点, 定义为Enum的泛型类<T 信息技术

    被认为有害的仿制药

        2
  •  1
  •   les2    16 年前

    使用有界类型的原因>这可能是由PECS经验法则(Joshua Bloch用有效Java解释)解释的。

    让我们检查具有此签名的任何抽象类。

    public abstract class Foo <E extends Foo<E>> {
    
       public static void use(Foo<E> foo) {
          // use foo
       }
    }
    

    以及另一个不使用有界通配符的抽象类:

    public abstract class Bar<E> {
       public static void use(Bar<E> bar)  {
          // use bar
       }
    }
    

    public class FooImpl extends Foo<FooImpl> {
      // ...
    }
    public class AnotherFooImpl extends Foo<AnotherFooImpl> { ... }
    
    public class BarImpl extends Bar<BarImpl> {
       ///
    }
    
    public class AnotherBarImpl extends Bar<AnotherBarImpl> { ... }
    

    我们的主要计划是:

    public class FooBar {
       public static void main(String[] args) {
          Foo.use(new FooImpl()); // works
          Foo.use(new AnotherFooImpl()); // works
    
          Bar.use(new BarImpl()); // doesn't work -- why?
          Bar.use(new AnotherBarImpl()); // doesn't work -- why?
       }
    }
    

    (我想不到,我还没有编译它,所以我希望我是对的:)

    每个枚举元素实际上都是枚举类型的子类:

    enum Foo {
       FooImpl, AnotherFooImpl, ...;
    }
    

    基本枚举类中有一些方法需要确保它们具有正确类型的子类,而要使其正常工作,语法是必需的。

    我希望这能有所帮助(如果你有时间,试试这个例子)。

    -- 发射脱离系统

        3
  •  1
  •   Jason S    16 年前

    就像 quining ! @第二课是正确的。

    public abstract class Foo <E extends Foo<E>> 
    {
    
       public static void use(Foo<E> foo) {
          // use foo
       }
    }
    

    如果您有以下课程:

    public class FooImpl extends Foo<FooImpl> {
      // ...
    }
    

    这些递归模板给你的魔力是:

    • 这个 Foo 模板要求其参数扩展自身(Foo)。
    • 如果参数类 E 反过来,扩展 Foo<E> 模板对其子类有“感知”,因为它的子类是作为模板参数传递给它的
    • 这反过来意味着 的方法可以安全地降低 this 指向其派生子类的指针 E
        4
  •  1
  •   ceyko    13 年前

    E 是的直接(通常是具体)子类 Enum ,与可比较的(枚举)实现一起使用 Comparable<E> Comparable<Enum> )还有其他一些方法。它是这样做的 访问实际的子类,我怀疑它也需要一些内部实现。

        5
  •  -1
  •   Oscar Chan    16 年前

    Enum类需要参数化类型E,它是Enum的子类。

    compareTo(EO)之类的方法需要类型信息E,它在类声明期间需要类型信息(例如Comparable)。

    Java编译器在创建枚举类时自动传递类型信息,所以在声明时不会看到它

    enum MyType {...}
    

    class String implements Comparable<String>
    
        6
  •  -1
  •   NawaMan    16 年前

    此类不是枚举数类型。它只是一个复杂的泛型正则类。很难说(没有看到全部代码)它为什么是这样设计的。但是我猜这可能与self类型的概念有关,因为您希望有一个方法始终返回当前类型。

    
    public abstract class Enum<E extends Enum<E>> {
        E getMe() { return (E)this; }
    }
    public class E1 extends Enum<E1> {
        void doE2_only() {}
        void doE2() {
            // This line is to prove that Javac will see this.getMe() as a function of E1
            this.getMe().doE2_only();
        }
    }
    public class E2 extends Enum<E2> {
        void doE2_only() {}
        void doE2() {
            // This line is to prove that Javac will see this.getMe() as a function of E2
            this.getMe().doE2_only();
        }
    }
    

    同样,这与枚举数类型无关。

    只是一个想法;

        7
  •  -1
  •   vdr    16 年前

    在代码中创建的所有枚举都将由扩展枚举类的最终类创建。

    public enum MyEnum { XYZ }
    

    将成为

    public final class MyEnum extends Enum<MyEnum>
    

    或者类似的东西(不确定XYZ是否成为一个实例或一个扩展它的类-我也认为它不是 真正地 最终,但编译器不允许您扩展枚举)。。。无论如何,这样的枚举并不是真正有用的,因为您自己不能(不应该)真正“做”任何事情。