使Java类具有通用性,但仅限于两种或三种类型

Joe*_*Joe 9 java generics

(我很惊讶不能在stackoverflow上找到这个问题,我只能在我的网上找到可怜的谷歌搜索,一定要指出重复...)

这是一个玩具类,它返回与你放入的相反的玩具类.目前它适用于整数,但只需要非常小的更改就可以使用String.

public class Mirror {

  int value;

  public int get() {
    return reverse(value);
  }

  private int reverse(int value2) {
    String valueString = value + "";
    String newString = reverse(valueString);
    return Integer.parseInt(newString);
  }

  private String reverse(String valueString) {
    String newString = "";
    for (char c : valueString.toCharArray()) {
      newString = c + newString;
    }
    return newString;
  }

  public void set(int value) {
    this.value = value;
  }

}
Run Code Online (Sandbox Code Playgroud)

我想做的是使类通用,但仅限于两种或三种可能的类型.所以我想写的是:

public class Mirror<X, where X is one of Integer, String, or MagicValue {

X value

public X get(){
[...]
Run Code Online (Sandbox Code Playgroud)

什么是正确的语法?我的Google-fu让我失望...... :(

编辑:似乎没有正确的语法,似乎无法完成,所以我的主要问题是:为什么?这似乎是人们在让这个课程变得非常通用之前可能想做的事情......

编辑编辑:管理今天为一些同事解决原因,所以添加了相关的原因以下答案.

Ale*_*exR 11

不幸的是,java不直接提供这样的功能.不过,我建议你做以下工作:

Mirror使用私有构造函数和3个静态工厂方法创建参数化类,这些方法创建Mirror具有特定参数的实例:

public class Mirror<T> {
    private T value
    private Mirror(T value) {
        this.value = value;
    }

    public static Mirror<Integer> integerMirror(Integer value) {
        return new Mirror(value);
    } 

    public static Mirror<String> stringMirror(String value) {
        return new Mirror(value);
    } 

    public static Mirror<MagicValue> magicMirror(MagicValue value) {
        return new Mirror(value);
    } 
}
Run Code Online (Sandbox Code Playgroud)

编辑 显然,您可以(并且可能应该)将类Mirror与其创建分开,例如将工厂方法放在单独的类中MirrorFactory.在这种情况下,构造函数应该成为包保护.

如果要支持大量但有限数量的类,则只能实现一个通用工厂方法

    public static <T> Mirror<T> createMirror(T value) {
        checkTypeSupported(value);
        return new Mirror(value);
    } 
Run Code Online (Sandbox Code Playgroud)

方法checkTypeSupported(value);可以使用某种metadatat(例如属性,JSON等文件)来获得支持的类型.但在这种情况下,您将无法享受编译时验证.

其他解决方案是要求所有支持的类型扩展某些基类或实现接口:

public class Mirror<T extends MyInterface> {}
Run Code Online (Sandbox Code Playgroud)

但是这个解决方案似乎不符合您的要求,因为您需要Integer,String并且MagicValue.