简体   繁体   English

使用非静态方法作为泛型枚举属性

[英]Using Non-Static Methods as Enum Properties with Generics

I'll try to keep this short. 我会尽量保持简短。 I'm trying to do something like this: 我正在尝试做这样的事情:

public enum Fruit {
    APPLE("Apple", appleHelper::doAppleThing),
    ORANGE("Orange", orangeHelper::doOrangeThing);

    private String name;
    private Function<String, List<T>> fruitFunction;

    Fruit(String name, Function<String, List<T>> fruitFunction) {
      this.name = name;
      this.fruitFunction = fruitFunction;
    }

    public String getName() {
      return name;
    }

    public <T> List<T> applyFruitFunction(String someString) {
      return fruitFunction.apply(someString);
    }
}

Such that later, I can have a method like 这样以后我可以有一个类似的方法

private <T> List<T> doFruitThing(String someString, Fruit fruit) {
    List<T> transformedFruits = fruit.applyFruitFunction(someString);

    if (transformedFruits.isEmpty()) {
        throw new FruitException("There was no fruit of type " + fruit.getName());
    }

    return transformedFruits;
}

There's two problems I'm running into here. 我在这里遇到两个问题。

  1. doAppleThing and doOrangeThing are not static methods, and ideally will stay that way, and I can't find any way of creating a local instance of appleHelper and orangeHelper to make the method reference work. doAppleThingdoOrangeThing不是静态方法,理想情况下会保持这种状态,而且我找不到任何方法来创建appleHelperorangeHelper的本地实例以使方法引用起作用。
  2. Even if I were to make the methods static, enums can't have Type parameters, so there's no way to have Function<String, List<T>> fruitFunction as a field. 即使我将方法设为静态,枚举也不能具有Type参数,因此也无法将Function<String, List<T>> fruitFunction作为字段。

Is there a way this can be done? 有办法吗? Or a better approach to this? 还是更好的方法呢?

Enum values can have their own method implementations. 枚举值可以有自己的方法实现。 So I would write this as: 所以我将其写为:

public enum Fruit {
    APPLE("Apple") {
        private final AppleHelper helper = new AppleHelper();

        @Override
        public <T> List<T> applyFruitFunction(String someString) {
            return helper.doAppleThing(someString);
        }
    },

    ORANGE("Orange") {
        private final OrangeHelper helper = new OrangeHelper();

        @Override
        public <T> List<T> applyFruitFunction(String someString) {
            return helper.doOrangeThing(someString);
        }
    };

    private String name;

    Fruit(String name) {
      this.name = name;
    }

    public String getName() {
      return name;
    }

    public abstract <T> List<T> applyFruitFunction(String someString);
}

However, if you get to the point of needing per-instance state for enum instances, the thing you have is less and less an enum and more of just an abstract base class. 但是,如果要达到枚举实例需要按实例状态的目的,那么拥有的东西将越来越少,而枚举又仅仅是抽象的基类。 It might be better to look into a more OO approach, using a factory/flywheel pattern for example, rather than being tied to a pure enum for this sort of thing. 最好是采用一种更面向对象的方法,例如使用工厂/飞轮模式,而不是将此类事情与纯粹的枚举联系在一起。 (It's hard to tell for sure because the code in the question is obviously just a simplified example.) (很难确定,因为问题中的代码显然只是一个简化的示例。)

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

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