当前位置: 首页 > 面试题库 >

使Java类通用,但仅适用于两种或三种类型

邹山
2023-03-14
问题内容

(我很惊讶无法在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;
  }

}

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

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

X value

public X get(){
[...]

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

编辑:似乎 没有 正确的语法,它似乎无法完成,所以我的主要问题是:为什么?这似乎是人们在使类 真正 通用之前可能要做的事情…

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


问题答案:

不幸的是,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);
    } 
}

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

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

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

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

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

public class Mirror<T extends MyInterface> {}

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



 类似资料:
  • 问题内容: 我试图弄清楚如何为通用类(在Swift中)实现类型约束,它将通用类型限制为仅数字类型。例如Double,Int等,但不是字符串。谢谢你的帮助。 问题答案: 您可以使用尖括号为通用类(对函数使用相同的语法)指定类型约束(使用类和协议): 要在单个类型上指定多个需求,请使用子句: 但是,您似乎无法在泛型参数子句中指定可选要求,因此一种可行的解决方案是创建一个协议,使所有数字类型都通过扩展来

  • 随着Swift的引入,我一直在努力了解这门新语言 我是一名iOS开发人员,会在应用程序中使用等类型。我注意到在苹果的“the Swift Programming Language”电子书中,他们使用了Swift类型 我注意到Swift类型没有(或者名称不同)Foundation类型所具有的某些功能。例如,具有属性。但是我没有找到类似的Swift。 我在想,对于一个iOS应用程序,我应该仍然使用基础

  • 我需要让对象的某些部分序列化默认值,而有些部分不序列化。 在下面的帖子中,我了解了如何根据类型做到这一点:Json。NET:如何使DefaultValueHandling仅适用于某些类型? 但是这个解决方案只适用于类型,不会是递归的。 预期行为: 重新序列化时: ContractProvider中是否有我可以重写的内容,或者我可以添加到成员或类中的属性来选择DefaultValueHandling

  • 我正在尝试编译我正在编写的Java Web应用程序,并且我遇到了编译错误,我不知道该怎么办。从我完成的谷歌搜索中,我发现了这个SO问题,但是提问者使用的是EJB,而我的错误是在JPA实体类中。 下面是maven构建错误。 这是我的用户类文件。 我查看了javax.persistence.Index JavaDoc,我的声明是正确的,所以我在这里被难住了,有人知道我做错了什么吗?感谢您的时间和考虑。

  • 我使用的是Typescript 3.2。2、无法实现最基本的类型防护: 这将产生源自。是否需要配置来启用此语法?

  • 问题内容: 有没有一种方法可以解决由两个互相引用的枚举引起的类加载问题? 我有两组枚举Foo和Bar,它们的定义如下: 上面的代码作为输出产生: 我知道为什么会发生- JVM开始对Foo进行类加载;它在Foo.A的构造函数中看到Bar.Alpha,因此开始加载Bar。它在对Bar.Alpha的构造函数的调用中看到Foo.A引用,但是(因为我们仍然在Foo.A的构造函数中)Foo.A此时为null,