gpt4 book ai didi

java - 从存储库加载后实例化泛型类

转载 作者:太空宇宙 更新时间:2023-11-04 07:42:59 25 4
gpt4 key购买 nike

为存储库(例如 Web 服务或数据库)编写类型处理程序时,我需要在从存储库加载值后实例化该类型。

假设我从存储库中获取了一个 String 值,并且有一个带有我可以使用的 String 参数的构造函数。如果返回类型有类型参数,除了实例化原始类型之外我还能做什么?似乎原始类型的存在只是为了与遗留代码兼容,所以我不想使用它们。

通常?可以用作类型参数(如果您知道类型在运行时是正确的),但在这种情况下不行,因为您无法使用通配符作为类型参数实例化类。

编辑:一些示例代码:

假设我有一个像这样的 PrimaryKey 类:

public class PrimaryKey<R extends RepositoryObject<R>> {
private String value;
public PrimaryKey(String value) {
this.value = value;
}
}

以及一组扩展RepositoryObject的类,其定义如下:

public class RepositoryObject<R extends RepositoryObject<R>> {
private PrimaryKey<R> pk;
public RepositoryObject(PrimaryKey<R> pk) {
this.pk = pk;
}
PrimaryKey<R> getPrimaryKey() {
return pk;
}
}

子类示例:

public class User extends RepositoryObject<User> {
public User(PrimaryKey<User> userId) {
super(userId);
}
}

现在 PrimaryKey 类的类型处理方法将如下所示:

public PrimaryKey<?> getValue(String stringValue) {
return new PrimaryKey<>(stringValue);
}

但这会导致编译器错误(在 Maven 构建中,而不是在 Eclipse IDE 中,奇怪的是),即使我使用的是菱形运算符,而不是在实例化时。也许由于某种原因,类型推断不能很好地工作,因为类型参数中存在递归。

最佳答案

在 Java 7 中,您通常可以使用 diamond operator出行 this limitation :

Container<?> c = new Container<>(arg);

否则您可以使用辅助工厂方法:

<T> Container<T> makeContainer(String arg) {
return new Container<T>(arg);
}

...

Container<?> c = makeContainer(arg);

编辑:

更新后,我可以看到您正在使用递归类型参数 <R extends RepositoryObject<R>> 。此编译错误是由于 javac 在通配符捕获和递归类型参数方面的限制所致。例如,请参阅此相关帖子:Java CRTP and Wildcards: Code compiles in Eclipse but not `javac`

不幸的是,使用原始类型作为解决方法是必要的,但它可以作为实现细节隐藏:

public PrimaryKey<?> getValue(String stringValue) {
@SuppressWarnings("rawtypes") //a raw type is necessary to placate javac
final PrimaryKey<?> pk = new PrimaryKey(stringValue);
return pk;
}

关于java - 从存储库加载后实例化泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15766290/

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