Java函数签名接受单个枚举值

时间:2019-05-26 02:10:47

标签: java

我有一个带有多个“类型”值的Java类,以及一个可以接受这些类型之一的类。

我试图根据使用Java的类型系统的Type枚举来更改构造函数的实现,但找不到有关如何执行此操作的任何信息。

public enum Type {
    A,
    B,
    C
}

public class Action {
    public Action(Type.A type, String value) {}
    public Action(Type.B type, Float value) {}
    public Action(Type.C type, String value) {}
}

在Java中可以实现这种效果吗?就像在Typescript中一样。

3 个答案:

答案 0 :(得分:13)

不,您编写的内容无法编译。

您可以命名工厂方法+私有构造函数以实现类似的结果:

public class Action {
  private Action(Type discriminator, String s, Float f) {...}
  public static ofA(String value) { return new Action(Type.A, value, null); }
  public static ofB(Float value)  { return new Action(Type.B, null, value); }
  public static ofC(String value) { return new Action(Type.C, value, null); }
}

构造函数可能会有许多if / else分支。 (抱歉,Java还没有代数类型和模式匹配。)

答案 1 :(得分:4)

您似乎要建模的是三种相关类型

  • A,带有字符串值,
  • B,具有浮点值,并且
  • C,带有字符串值。

如果是这样的话,Java几乎希望您创建一个抽象基类的三个子类A,B和C,因为Java并没有真正做不相交和类型(又名不相交联合类型,标记联合)类型)。

this StackOverflow question中讨论了有关如何使用带有“标签”的单个类型的信息(这是名称为标签的并集或标签的总和的来源)。由于提供了许多想法,因此最好在某个时候检查一下该问题。大多数使用泛型。

恕我直言,Java从来没有真正获得求和类型的正确方法。 Java 8引入了可选的选项,但引入了“仅可选的”选项,因此适当的总和类型需要一些工作。

因此,在此期间,请考虑通常的Java解决方法:

  • 子类(叹气)
  • 静态工厂方法(因为不能用枚举重载构造函数:A,B和C都属于同一类型)。

编辑:看到@ 9000的一个很好的答案,它确切地显示了如何实现静态工厂方法。

答案 2 :(得分:0)

像A和C的外观来自相同的“类型”家族,而B属于另一种类型。 在这种情况下,您应该定义两种类型。 如果您希望能够将两种类型都视为同一个“族”,请让它们实现相同的接口:

interface Type {
}

enum Type1 implements Type {
    A,
    C
}

enum Type2 implements Type {
    B
}



public class Action {
    public Action(Type1 type, String value) {}
    public Action(Type2 type, Float value) {}        
}