Java 使用枚举泛型生成代码

Java 使用枚举泛型生成代码,java,enums,Java,Enums,我有一段代码,最初只为一个团队设计,他们将enum[存储任务列表]传递给api。然后,此api将此枚举的使用编程到许多其他类 现在我有了一个任务,其中这些代码需要由多个团队使用,他们可以以枚举的形式传递自己的任务集 考虑到当前的实现,我认为支持多个团队彻底修改代码是不可行的,因为enum不能扩展其他enum 有没有办法在不进行大量更改的情况下实现此功能?您可能不应该为此使用枚举,但如果需要,可以在帮助器类或一组相互扩展的类中实现逻辑,并使枚举成为一个精简的包装器: public enum MyT

我有一段代码,最初只为一个团队设计,他们将enum[存储任务列表]传递给api。然后,此api将此枚举的使用编程到许多其他类

现在我有了一个任务,其中这些代码需要由多个团队使用,他们可以以枚举的形式传递自己的任务集

考虑到当前的实现,我认为支持多个团队彻底修改代码是不可行的,因为enum不能扩展其他enum


有没有办法在不进行大量更改的情况下实现此功能?

您可能不应该为此使用枚举,但如果需要,可以在帮助器类或一组相互扩展的类中实现逻辑,并使枚举成为一个精简的包装器:

public enum MyTaskEnum {
    A, B, C;

    private final TaskEnumHelper helper = new TaskEnumHelper();

    public void foo (int x, int y)
    {
        helper.foo (x, y);
    }
}

您可能不应该为此使用枚举,但如果需要,可以在帮助器类或一组相互扩展的类中实现逻辑,并使枚举成为一个精简包装器:

public enum MyTaskEnum {
    A, B, C;

    private final TaskEnumHelper helper = new TaskEnumHelper();

    public void foo (int x, int y)
    {
        helper.foo (x, y);
    }
}

相对来说,使围绕枚举的大部分工作变得通用是比较容易的

下面是一个严重精简的示例。它定义了一个通用数据库表类,该类将枚举列作为其定义类型。枚举定义表中的列。定义类型是一个枚举,它还实现了一个接口,这是一个非常有用的技巧

public class Table<Column extends Enum<Column> & Table.Columns> {
  // Name of the table.
  protected final String tableName;
  // All of the columns in the table. This is actually an EnumSet so very efficient.
  protected final Set<Column> columns;

  /**
   * The base interface for all Column enums.
   */
  public interface Columns {
    // What type does it have in the database?
    public Type getType();
  }

  // Small list of database types.
  public enum Type {
    String, Number, Date;
  }

  public Table(String tableName,
               Set<Column> columns) {
    this.tableName = tableName;
    this.columns = columns;
  }

}
现在,您可以使用以下内容创建真正的表:

public class VersionTable extends Table<VersionTable.Column> {

  public enum Column implements Table.Columns {
    Version(Table.Type.String),
    ReleaseDate(Table.Type.Date);

    final Table.Type type;

    Column(Table.Type type) {
      this.type = type;
    }

    @Override
    public Type getType() {
      return type;
    }
  }

  public VersionTable() {
    super("Versions", EnumSet.allOf(Column.class));
  }
}
请注意,这是一个非常简单的示例,但只需做一点工作,就可以轻松地将大量枚举工作移动到父类中


这项技术确实保留了使用泛型时得到的类型安全检查。

相对来说,围绕枚举进行大量泛型工作比较容易

下面是一个严重精简的示例。它定义了一个通用数据库表类,该类将枚举列作为其定义类型。枚举定义表中的列。定义类型是一个枚举,它还实现了一个接口,这是一个非常有用的技巧

public class Table<Column extends Enum<Column> & Table.Columns> {
  // Name of the table.
  protected final String tableName;
  // All of the columns in the table. This is actually an EnumSet so very efficient.
  protected final Set<Column> columns;

  /**
   * The base interface for all Column enums.
   */
  public interface Columns {
    // What type does it have in the database?
    public Type getType();
  }

  // Small list of database types.
  public enum Type {
    String, Number, Date;
  }

  public Table(String tableName,
               Set<Column> columns) {
    this.tableName = tableName;
    this.columns = columns;
  }

}
现在,您可以使用以下内容创建真正的表:

public class VersionTable extends Table<VersionTable.Column> {

  public enum Column implements Table.Columns {
    Version(Table.Type.String),
    ReleaseDate(Table.Type.Date);

    final Table.Type type;

    Column(Table.Type type) {
      this.type = type;
    }

    @Override
    public Type getType() {
      return type;
    }
  }

  public VersionTable() {
    super("Versions", EnumSet.allOf(Column.class));
  }
}
请注意,这是一个非常简单的示例,但只需做一点工作,就可以轻松地将大量枚举工作移动到父类中

这种技术确实保留了使用泛型时得到的类型安全检查。

但是。。。枚举可以实现接口,例如:

public interface Task {
    int getPriority(); // just for example
    // plus whatever methods define a task
}

public enum Team1Task implements Task {
    Task1(1),
    Task2(3);
    private final int priority;
    private Team1Task(int priority) {
        this.priority = priority;
    }
    public int getPriority() {
        return priority;
    }
}
现在,我们可以使用java generic kung fu来指定绑定到适当枚举的泛型参数:

public class TaskProcessor<T extends Enum<T> & Task> {
    public void process(T task) {
        // do something with task
    }
}
要使用它:

TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance
仅供参考,出于对泛型的好奇,您也可以使用此绑定来实现相同的目标:

public class TaskProcessor<T extends Enum<? extends Task>> {
虽然我找不到实际效果上的差异,但我发现它缺乏上述交叉口边界的清晰性和熟悉的模式。有关这方面的更多信息,请参见。

但是。。。枚举可以实现接口,例如:

public interface Task {
    int getPriority(); // just for example
    // plus whatever methods define a task
}

public enum Team1Task implements Task {
    Task1(1),
    Task2(3);
    private final int priority;
    private Team1Task(int priority) {
        this.priority = priority;
    }
    public int getPriority() {
        return priority;
    }
}
现在,我们可以使用java generic kung fu来指定绑定到适当枚举的泛型参数:

public class TaskProcessor<T extends Enum<T> & Task> {
    public void process(T task) {
        // do something with task
    }
}
要使用它:

TaskProcessor<Team1Task> p = new TaskProcessor<Team1Task>();
p.process(Team1Task.Open); // will only accept a Team1Task instance
仅供参考,出于对泛型的好奇,您也可以使用此绑定来实现相同的目标:

public class TaskProcessor<T extends Enum<? extends Task>> {

虽然我找不到实际效果上的差异,但我发现它缺乏上述交叉口边界的清晰性和熟悉的模式。有关这方面的更多信息,请参见。

枚举可以实现接口。我建议为任务提供一个合理的接口。让您的枚举实现该接口,您的代码将继续正常工作。其他团队可以使用他们希望自己的enum或其他东西的任何接口实现。注意,如果没有代码,很难做出非常明确的建议。

枚举可以实现接口。我建议为任务提供一个合理的接口。让您的枚举实现该接口,您的代码将继续正常工作。其他团队可以使用他们希望自己的enum或其他东西的任何接口实现。请注意,如果没有代码,就很难提出非常明确的建议。

代码值1024个字,几个演示当前结构和您认为可能存在问题的结构的简短片段将非常有用。不同的团队是否共享类似的任务?它们在各自的集合中是否都是唯一的?@cgatian:任务基本上涉及从数据库获取数据,因此是的,功能类似的任务。代码值1024个字,几个简短的片段演示当前结构和您认为有问题的结构会非常有用。不同的团队是否共享类似的任务?它们各自有自己的集合吗?@cgatian:任务基本上涉及从数据库获取数据,所以是的,功能相似。+1-作为泛型的好奇。。。有趣又奇怪。@OldCurmudgeon我最近才意识到这是可能的,甚至要求a确认它在效果上是相同的-共识是“是+1”-作为对泛型的好奇。。。有趣又奇怪。@OldCurmudgeon我最近才意识到这是可能的,甚至要求a确认它在效果上是相同的-一致意见是肯定的