Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中,这种枚举类型编译成什么?_Java_Enums_Java 8_Enumeration - Fatal编程技术网

在java中,这种枚举类型编译成什么?

在java中,这种枚举类型编译成什么?,java,enums,java-8,enumeration,Java,Enums,Java 8,Enumeration,下面是定义枚举类型的代码 enum Company{ EBAY(30), PAYPAL(10), GOOGLE(15), YAHOO(20), ATT(25); private int value; private Company(int value){ super(this.name()); this.value = value; } public int getValue(){ return val

下面是定义枚举类型的代码

enum Company{
    EBAY(30), PAYPAL(10), GOOGLE(15), YAHOO(20), ATT(25);
    private int value;

    private Company(int value){
        super(this.name()); 
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}
内部编译为

final class Company extends Enum<Company>{
    public final static Company EBAY = new Company(30);
    public final static Company PAYPAL = new Company(10);
    public final static Company GOOGLE = new Company(15);
    public final static Company YAHOO = new Company(20);
    public final static Company ATT = new Company(25);

    private int value;

    private Company(int value){
        super(this.name(),Enum.valueOf(Company.class, this.name()));
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}
最终类公司扩展枚举{
公开最终静态公司易趣=新公司(30);
公开最终静态公司PAYPAL=新公司(10);
公开最终静态公司谷歌=新公司(15);
公开最终静态公司雅虎=新公司(20);
公开最终静态公司ATT=新公司(25);
私有int值;
私人公司(国际价值){
super(this.name(),Enum.valueOf(Company.class,this.name());
这个值=值;
}
public int getValue(){
返回值;
}
}

我的理解正确吗?

从功能上讲,是的。字面上说是不(一方面,您不能显式地将类
Enum
作为子类)<代码>枚举有一个
toString
。并且您的
enum
不是有效的代码(您不能调用
super()
),并且
getValue
需要返回类型

enum Company{
    EBAY(30), PAYPAL(10), GOOGLE(15), YAHOO(20), ATT(25);
    private int value;

    private Company(int value){
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

如果您删除对
super
的调用,这是非法的,
this.name
作为super的参数也是非法的,请编译它并在类上运行javap,这是输出:

$ /usr/lib/jvm/java-7-oracle/bin/javap -p Company.class 
Compiled from "Company.java"
final class Company extends java.lang.Enum<Company> {
  public static final Company EBAY;
  public static final Company PAYPAL;
  public static final Company GOOGLE;
  public static final Company YAHOO;
  public static final Company ATT;
  private int value;
  private static final Company[] $VALUES;
  public static Company[] values();
  public static Company valueOf(java.lang.String);
  private Company(int);
  public int getValue();
  static {};
}
$/usr/lib/jvm/java-7-oracle/bin/javap-p Company.class
从“Company.java”编译而来
最终类公司扩展了java.lang.Enum{
公开静态最终公司易趣;
公开静态最终公司贝宝;
公开静态最终公司谷歌;
公开静态最终公司雅虎;
公开静态最终公司ATT;
私有int值;
私人静态最终公司[]$价值;
上市公司[]价值观();
public static Company valueOf(java.lang.String);
私人公司(int);
public int getValue();
静态{};
}
这里是静态字节码,它的一部分

static {};
  flags: ACC_STATIC
  LineNumberTable:
    line 2: 0
    line 1: 75
  Code:
    stack=5, locals=0, args_size=0
       0: new           #4                  // class Company
       3: dup           
       4: ldc           #8                  // String EBAY
       6: iconst_0      
       7: bipush        30
       9: invokespecial #9                  // Method "<init>":(Ljava/lang/String;II)V
      12: putstatic     #10                 // Field EBAY:LCompany;
static{};
标志:ACC_静态
LineNumberTable:
第2行:0
第1行:75
代码:
堆栈=5,局部变量=0,参数大小=0
0:新#4//级公司
3:dup
4:ldc#8//String易趣
6:iconst_0
7:bipush 30
9:invokespecial#9//Method“”:(Ljava/lang/String;II)V
12:putstatic#10//Field易趣:L公司;

几乎,您的第二个代码片段确实很好地表示了编译器内部生成的内容(字节码),但是,它并不完全相同

编译的枚举将包含
ACC_ENUM
标志,该标志指示该类或其超类被声明为枚举类型,并将被JVM视为枚举类型

您的第二个代码段(假设它可以编译)不会在字节码中包含此标志:


枚举

final class Company extends java.lang.Enum<Company>
      minor version: 0
      major version: 52
      flags: ACC_FINAL, ACC_SUPER, ACC_ENUM


至于剩下的逻辑(仍然假设它可以编译),它是正确的。在内部,枚举将表示为扩展
java.lang.Enum
final
类。但是,请注意,您不能直接扩展
java.lang.Enum
自己,因为这是由编译器在创建枚举时完成的,如果您自己尝试,则会导致编译错误。

奇怪。对于“Company c1=Company.EBAY;”,对象创建在哪里?@overexchange in
static{}
,如果您想要字节码,可以发布它,但不确定它是否有意义。但是在加载和初始化类时,static{}将执行一次。那么,该块是否为每个成员创建对象?其余字段如何?@overexchange也许您最好运行
/usr/lib/jvm/java-7-oracle/bin/javap-c-v-l-p Company.class
。手工制作的类和正确的枚举上的类属性和字段属性将不匹配。
类公司
不能显式地子类
类java.Lang.enum
?我没有得到你。像
ordinal()
/
values()
这样的方法对于
class Company
类型的对象在没有子类化的情况下是如何可见的?@overexchange它确实是子类
java.lang.Enum
你可以通过查看字节码来确认它,但是你自己不能子类
java.lang.Enum
;正如我所解释的,这根本无法编译。此扩展是由编译器本身添加的。如果使用较旧的编译器,则可以创建扩展
Enum
的类…
final class Company
  minor version: 0
  major version: 52
  flags: ACC_FINAL, ACC_SUPER