gpt4 book ai didi

java - 使用一组固定类型中的一个来参数化一个类

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:37:27 24 4
gpt4 key购买 nike

假设我有一个泛型类 Foo,它可以容纳一个类型为 T 的对象。此外,假设我希望能够使用两种类型之一的对象来实例化类。最后,假设这两种类型的最低公共(public)上限是一种类型,其子类比我想要允许的这两种类型多得多,所以我不能简单地为类型参数指定上限(如 class Foo<T extends Something> ), 因为这样我就可以用我期望的两种类型之外的其他类型来实例化类。

为了说明,假设我希望 Foo 保存 StringInteger 。最低的公共(public)上限是 Object ,因此指定上限不会奏效。

当然,我可以按照以下方式做一些事情

class Foo<T> {

private T obj;

public Foo(T obj) throws IllegalArgumentException {
if (!(obj instanceof String || obj instanceof Integer)) {
throw new IllegalArgumentException("...");
}
this.obj = obj;
}
}

但是,在这种情况下,我仍然可以使用任何 对象调用构造函数;如果我尝试用既不是 String 也不是 Integer 的东西来实例化它,我将在运行时得到一个异常。

我想做得更好。我希望编译器静态推断(即,在编译时)我只能使用 StringInteger 的对象实例化此类。

我在想沿着这些思路做的事情可能会成功:

class Foo<T> {

private T obj;

public Foo(String s) {
this((T) s);
}

public Foo(Integer i) {
this((T) i);
}

private Foo(T obj) {
this.obj = obj;
}
}

这行得通,但看起来真的很奇怪。编译器警告(可以理解)关于未经检查的强制转换。当然我可以抑制这些警告,但我觉得这不是要走的路。此外,看起来编译器实际上无法推断类型 T 。我惊讶地发现,使用类 Foo 的后一个定义,我可以这样做,例如:

Foo<Character> foo = new Foo<>("hello");

当然这里的类型参数应该是String,而不是Character。但是编译器让我摆脱了上述分配。

  1. 有没有办法实现我想要的,如果有,怎么做?
  2. 附带问题:为什么编译器允许我对上面类型为 Foo<Character> 的对象进行赋值,甚至连 警告 都没有(在使用类 Foo 的后一个定义时)? :)

最佳答案

尝试使用static 工厂方法来防止编译器警告。

class Foo<T> {

private T obj;

public static Foo<String> of(String s) {
return new Foo<>(s);
}

public static Foo<Integer> of(Integer i) {
return new Foo<>(i);
}

private Foo(T obj) {
this.obj = obj;
}
}

现在您使用以下方式创建实例:

Foo<String> foos = Foo.of("hello");

Foo<Integer> fooi = Foo.of(42);

Foo<Character> fooc = Foo.of('a'); // Compile error

但是以下内容仍然有效,因为您可以声明任何类型 T 的 Foo,但不能实例化它:

Foo<Character> fooc2;

Foo<Character> fooc3 = null;

Foo<Object> fooob1;

Foo<Object> fooob2 = null;

关于java - 使用一组固定类型中的一个来参数化一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48993454/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com