繁体   English   中英

Java Enum表现得非常奇怪

[英]Java Enum behaving very weird

我在我的代码中定义了以下枚举:

public enum Table {
  BASE_PRICES("base_prices", Affinity.UPS,
          Arrays.asList(
                  Field.BILLING_WEIGHT_LOWER_BOUND,
                  Field.BILLING_WEIGHT_UPPER_BOUND,
                  Field.BASE_PRICE,
                  Field.SERVICE_TYPE_ID,
                  Field.ZONE_ID
          )),

  COUNTRY_CODES("country_codes", Affinity.UPS,
          Arrays.asList(Field.COUNTRY_CODE)),

  SERVICE_TYPES("service_types", Affinity.UPS,
          Arrays.asList(Field.SERVICE_TYPE)),

  ZONE_DIVISION("zone_division", Affinity.UPS,
          Arrays.asList(
                  Field.COUNTRY_CODE_ID,
                  Field.SERVICE_TYPE_ID,
                  Field.ZONE_ID,
                  Field.POST_CODE_LOWER_BOUND,
                  Field.POST_CODE_UPPER_BOUND)),

  ZONES("zones", Affinity.UPS,
          Arrays.asList(Field.ZONE_CODE));

  // used to denote the affinity of a table for
  // affinity specific DB cleanup and other stuff.
  public enum Affinity {
    UPS
  }

  private String name;
  private Affinity affinity;
  private List<Field> fields;

  private Table(String name, Affinity affinity, List<Field> fields){
    this.name = name;
    this.affinity = affinity;
    this.fields = fields;
    System.out.println("ENUM CONSTRUCTOR (" + name + "):");
    System.out.println(fields);
    System.out.println();
  }

  public List<Field> getFields(){
    return Collections.unmodifiableList(fields);
  }

}

当我使用枚举运行单个JUnit测试时,一切都很好。 但是,当我运行整个测试套件时,在使用空指针异常失败之前隔离工作的相同测试,由于枚举未正确初始化,枚举构造函数中println的输出为:

ENUM CONSTRUCTOR (base_prices):
[BILLING_WEIGHT_LOWER_BOUND, BILLING_WEIGHT_UPPER_BOUND, BASE_PRICE, null, null]

ENUM CONSTRUCTOR (country_codes):
[COUNTRY_CODE]

ENUM CONSTRUCTOR (service_types):
[null]

ENUM CONSTRUCTOR (zone_division):
[null, null, null, null, null]

ENUM CONSTRUCTOR (zones):
[null]

大多数字段(字段也是枚举)由于某些我无法理解的原因而为空,但只有在我执行整个测试套件时才会出现这种情况。

我完全无能为力,任何建议都非常感谢。

谢谢!

我认为你在TableField之间有一个类加载循环。

请考虑以下枚举:

enum A {
    X(B.Z),

    A(B b) {
        System.out.println("Constructing " + name() + ": " + b);
    }
}

enum B {
    Z(A.X);

    B(A a) {
        System.out.println("Constructing " + name() + ": " + a);
    }
}

因为A引用B ,加载A导致B被加载; 但是B引用A ,导致A被加载 - 除了它已经被加载,所以你在构造Z时看到未初始化的字段值( null )。

Ideone演示

你需要识别这个循环(它可能不是像这样的长度为2的循环,并且可能不仅涉及枚举类,因此它可能不完全明显;存在用于识别代码中的循环依赖性的工具)并打破它。

尝试执行上面给出的代码,它对我来说很有效,假设Field是enum(附在这里)。 它使用以下代码生成所需的输出:

public class Runner {    
    public static void main(String[] args) {
        System.out.println(Table.BASE_PRICES);

    }    
}


public enum Field {
    BILLING_WEIGHT_LOWER_BOUND, BILLING_WEIGHT_UPPER_BOUND, BASE_PRICE, SERVICE_TYPE_ID, ZONE_ID, 
    COUNTRY_CODE, SERVICE_TYPE, COUNTRY_CODE_ID, POST_CODE_LOWER_BOUND, POST_CODE_UPPER_BOUND, ZONE_CODE;

}

ENUM CONSTRUCTOR(base_prices):[BILLING_WEIGHT_LOWER_BOUND,BILLING_WEIGHT_UPPER_BOUND,BASE_PRICE,SERVICE_TYPE_ID,ZONE_ID]

ENUM CONSTRUCTOR(country_codes):[COUNTRY_CODE]

ENUM CONSTRUCTOR(service_types):[SERVICE_TYPE]

ENUM CONSTRUCTOR(zone_division):[COUNTRY_CODE_ID,SERVICE_TYPE_ID,ZONE_ID,POST_CODE_LOWER_BOUND,POST_CODE_UPPER_BOUND]

ENUM CONSTRUCTOR(区域):[ZONE_CODE]

如果你在这里做了不同的事情,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM