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

如何从另一个类的生成器中引用枚举字段?

  •  0
  • tobiasfried  · 技术社区  · 7 年前

    我使用构建器模式在游戏中创建项目对象,我希望能够使用项目前缀和后缀生成随机项目,如 Item.builder().random().build() . 前缀和后缀都是字段参差不齐的枚举。他们都有一个 name 但有些人 damage luck 例如,字段。如何从生成器中访问枚举字段?

    我在每个枚举中都有返回随机前缀和后缀的公共方法,我的项生成器的随机化方法调用这些方法并在本地存储词缀。但我似乎无法通过反射获得它们的成员变量。 prefix.getClass().getDeclaredField("name").toString 收益率 java.lang.String roan.ItemPrefix$2.name 而不是实际的名字。另外,在我看来,这很糟糕。

    枚举:

    enum Prefix {
        ARROGANT {
            String name = "Arrogant ";
            int damage = 20;
            int luck = 2;
        },
        BLOODY {
            String name = "Bloody ";
            int damage = 30;
        },
        CURIOUS {
            String name = "Curious ";
            int luck = 4;
        },
    
        private static final int size = Prefix.values().length;
    
        public static Prefix randomPrefix() {
            return Prefix.values()[Dice.roll(Prefix.size)];
        }
    }
    

    建设者:

    public static abstract class Builder<T extends Builder<T>> {
        // Default values
        private String name = "itemName"; 
        private int damage = 5;
        private int luck = 0;  
    
        protected abstract T self();
    
        public T name(String name) {
            this.name = name;
            return self();
        }
    
        // More builder methods
        ...
    
        // PROBLEMATIC CODE
        public T random() {
            Prefix prefix = Prefix.randomPrefix();
            this.name = prefix.getClass().getDeclaredField("name").toString();
            return self();
            }
    
            public Item build() {
                return new Item(this);
            }
        }
    }
    
    // Builder helper classes
    ...
    

    理想情况下,它将使用传递给它的枚举的成员字段组装完全成形的项。我在用 enum Prefix 而不是前缀对象的数组,因为我想在其他地方对 Item 喜欢 Armor ,只能使用某些前缀。

    1 回复  |  直到 7 年前
        1
  •  2
  •   CoronA    7 年前

    当前的设计依赖于枚举前缀的3个匿名子类。这是不必要的。不妨尝试一下:

    enum Prefix {
      ARROGANT ("Arrogant ",20,2), BLOODY("Bloody ",30,0), CURIOUS("Curious ",5, 4);
    
      public String name = "itemName"; 
      public int damage = 5;
      public int luck = 0;  
    
      Prefix(String name, int damage, int luck) {
        this.name = name;
        this.damage = damage;
        this.luck = luck;
      }
    
      ...
    }
    

    因此,您不需要反射来访问字段。

    如果你真的想要替代品 arrogant , bloody , curious 要使用不同的模式,枚举的决策是错误的。而是在工厂列表中随机选择,每个工厂都会返回此随机选择的完全正确的配置项。