Java';什么是枚举声明?
在浏览Java的源代码时,我发现了以下声明:Java';什么是枚举声明?,java,generics,Java,Generics,在浏览Java的源代码时,我发现了以下声明: public abstract class Enum<E extends Enum<E>> 公共抽象类枚举 应该如何解释?我被它困住了 谢谢你。你并不孤单。我不得不说: 或者,简单地说,说明同样的观点, 考虑一下:EnUM实际上是一个 泛型类定义为枚举。你认为 把它弄出来。我们放弃了解释 它 (来自被认为有害的博客条目泛型)Enum类需要一个参数化类型E,它是Enum的子类 compareTo(EO)之类的方法需要类型信息
public abstract class Enum<E extends Enum<E>>
公共抽象类枚举
应该如何解释?我被它困住了
谢谢你。你并不孤单。我不得不说:
或者,简单地说,说明同样的观点,
考虑一下:EnUM实际上是一个
泛型类定义为枚举。你认为
把它弄出来。我们放弃了解释
它
(来自被认为有害的博客条目泛型)Enum类需要一个参数化类型E,它是Enum的子类 compareTo(EO)之类的方法需要类型信息E,它在类声明期间需要类型信息(例如Comparable) Java编译器在创建枚举类时自动传递类型信息,所以在声明时不会看到它
enum MyType {...}
有些东西我不喜欢通用的用法。例如,当接口只需要类信息时,为什么我们需要将类类型详细地传递给接口?我们不能有默认值,或者编译器现在不够聪明
e、 g
类字符串实现了可比较的
E
是Enum
的直接(通常是具体的)子类,与compariable(Enum实现compariable
notcompariable
)和一些其他方法一起使用。它是这样做的
访问实际的子类,我怀疑它也需要一些内部实现。此类不是枚举器类型。它只是一个复杂的泛型正则类。很难说(没有看到全部代码)它为什么是这样设计的。但是我猜这可能与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();
}
}
公共抽象类枚举{
E getMe(){返回(E)this;}
}
公共类E1扩展了Enum{
void doE2_only(){}
无效doE2(){
//这一行是为了证明Javac将把这个.getMe()看作E1的函数
这个.getMe().doE2_only();
}
}
公共类E2扩展了枚举{
void doE2_only(){}
无效doE2(){
//这一行是为了证明Javac将把这个.getMe()看作是E2的函数
这个.getMe().doE2_only();
}
}
同样,这与枚举数类型无关
只是一个想法 在代码中创建的所有枚举都将由扩展枚举类的最终类创建
public enum MyEnum { XYZ }
将成为
public final class MyEnum extends Enum<MyEnum>
public final类MyEnum扩展了Enum
或者类似的东西(不确定XYZ是否成为一个实例或一个扩展它的类-我也认为它不是真正的最终版本,但编译器不允许您扩展枚举)。。。无论如何,这样的枚举并不是真正有用的,因为您自己不能(不应该)真正“做”任何事情
阅读它的javadoc/代码,更好地理解您可以(不可以)对枚举做什么,这仍然是间接有用的。使用绑定类型>的原因可能是由PECS经验法则解释的(Joshua Bloch用有效的Java解释)
PECS代表“Producer,extends;Consumer super”,它是一个首字母缩略词,解释了在设计泛型方法时如何以及何时使用有界通配符 让我们检查具有此签名的任何抽象类
public abstract class Foo <E extends Foo<E>> {
public static void use(Foo<E> foo) {
// use foo
}
}
要使Bar.use(new BarImpl())工作,必须使用通配符
(我想不到,我还没有编译它,所以我希望我是对的:)
每个枚举元素实际上都是枚举类型的子类:
enum Foo {
FooImpl, AnotherFooImpl, ...;
}
基本枚举类中有一些方法需要确保它们具有正确类型的子类,而要使其正常工作,语法是必需的
我希望这能有所帮助(如果你有时间,试试这个例子)
--
LES就像@第二课是正确的
public abstract class Foo <E extends Foo<E>>
{
public static void use(Foo<E> foo) {
// use foo
}
}
公共抽象类Foo
{
公共静态无效使用(Foo-Foo){
//使用foo
}
}
如果您有以下课程:
public class FooImpl extends Foo<FooImpl> {
// ...
}
public类FooImpl扩展了Foo{
// ...
}
这些递归模板给你的魔力是:
模板要求其参数扩展自身(Foo)Foo
- 如果参数类
反过来扩展了E
(由于上一点,它必须扩展),那么您已经确保Foo
模板具有对其子类的“感知”,因为它的子类作为模板参数传递到模板中Foo
- 这反过来意味着
的方法可以安全地将Foo
指针向下投射到它的派生子类this
李>E
publicstaticvoiduse(Foo-Foo)
和publicstaticvoiduse(Bar)
不按编写的方式编译(您尝试过吗?)。它们不在E
的范围内。”这反过来意味着Foo的方法可以
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, ...;
}
public abstract class Foo <E extends Foo<E>>
{
public static void use(Foo<E> foo) {
// use foo
}
}
public class FooImpl extends Foo<FooImpl> {
// ...
}