本文介绍了使Java类通用,但仅适用于两种或三种类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我很惊讶无法在stackoverflow上找到这个问题,我只能归咎于糟糕的谷歌搜索,必须指出所有重复的问题...)

(I was astonished not to be able to find this question already on stackoverflow, which I can only put down to poor googling on my part, by all means point out the duplicate...)

这里是一个玩具类,它返回您放入玩具类中的反向类.目前,它适用于整数,但只需要很小的改动就可以适用于String.

Here is a toy class that returns the reverse of what you put into it. Currently it works on integers, but would require only very minor changes to work for 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;
  }

}

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

What I'd like to do is make the class generic, but only for, say, two or three possible types. So what I want to write is:

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

X value

public X get(){
[...]

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

What's the correct syntax? My Google-fu is failing me... :(

看来不是正确的语法,而且看来似乎没有完成,所以我的主要问题是:为什么?这似乎是人们在使类成为 truly 泛型之前可能要做的事情……

it appears there isn't a correct syntax and it can't appear to be done, so my main question is: why? this seems like the sort of thing that people might want to do before they made the class truly generic...

编辑今天设法与一些同事一起弄清了为什么,因此在下面添加了相关的为什么"答案.

EDIT Managed to work out the why with some labmates today, so added the relevant why answer below.

推荐答案

不幸的是,java没有直接提供这种功能.但是,我建议您采取以下解决方法:

Unfortunately java does not provide such functionality directly. However I can suggest you the following work around:

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

Create parametrized class Mirror with private constructor and 3 static factory methods that create instance of Mirror with specific parameter:

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);
    }
}

编辑显然,您可以(可能应该)将类Mirror从其创建中分离出来,例如将工厂方法放在单独的类MirrorFactory中.在这种情况下,构造函数应受到程序包的保护.

EDITObviously you can (and probably should) separate the class Mirror from its creating, e.g. put the factory methods to separate class MirrorFactory. In this case the constructor should become package protected.

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

If you want to support large yet limited number of classes you can implement only one generic factory method

    public static <T> Mirror<T> createMirror(T value) {
        checkTypeSupported(value);
        return new Mirror(value);
    }

方法checkTypeSupported(value);可能使用某种元数据(例如属性,JSON等文件)来获取受支持的类型.但是,在这种情况下,您将不会享受编译时验证.

Method checkTypeSupported(value); may use some kind of metadatat (e.g. properties, JSON etc file) to get supported types. In this case however you will not enjoy the compile time validation.

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

Other solution is to require that all supported types extend certain base class or implement interface:

public class Mirror<T extends MyInterface> {}

但是此解决方案似乎不符合您的要求,因为您需要IntegerStringMagicValue.

But this solution seems does not match your requirements since you need Integer, String and MagicValue.

这篇关于使Java类通用,但仅适用于两种或三种类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-23 13:23