gpt4 book ai didi

Java 泛型和可序列化

转载 作者:搜寻专家 更新时间:2023-10-31 20:01:39 24 4
gpt4 key购买 nike

我们创建了一个抽象类,用于处理 Redis(设置/获取值),如下所示:

public abstract class AbstractCachedSupport<T extends Serializable> {
protected T get(CacheKey key, Supplier<T> supplier) {...}
// ...
}

我不满意的是我们在扩展这个类时不能使用像List、Map这样的接口(interface):

public class CachedMap extends AbstractCachedSupport<Map<String, Integer>>

因为它们不扩展 Serializable,所以我们必须始终使用具体类:

public class CachedMap extends AbstractCachedSupport<HashMap<String, Integer>>

不用说,当从一个具体类迁移到另一个具体类时,这会带来一些问题。这也不是我称之为最佳实践的东西,但也许只有我就是这样。

另一种让我们可以灵活地使用接口(interface)的替代方法是删除有界类型并在运行时检查 T 是否扩展了 Serializable:

public abstract class AbstractCachedSupport<T> {
public AbstractCachedSupport() {
final Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
if (!Serializable.class.isAssignableFrom(type)) {
throw new RuntimeException("T must extend Serializable");
}
}

protected T get(CacheKey key, Supplier<T> supplier) {...}
// ...
}

这让我们没有编译时检查 T 扩展可序列化,这也不是一件好事。

你知道我们可以优雅地解决这个问题的任何其他方式吗?您愿意使用第一个(有界类型参数)还是第二个(仅运行时检查)?

折衷方案是首先使用容器类来保存集合:

public class IntegerParamsContainer implements Serializable {
private static final long serialVersionUID = 1L;
private Map<String, Integer> map;
}

public class CachedMap extends AbstractCachedSupport<IntegerParamsContainer>

但这最终与第二个问题相同:没有编译时检查,责任落在开发人员的肩上,始终使用实现 Serializable 的集合。

编辑:一些扩展 AbstractCachedSupport 的类是 Spring(当前版本 4.1)组件类,它们不被称为 CachedMap或类似的东西,而不是CityAutocompleteDataBean , WrParamsDataBean ETC..如果我们向这些组件类添加泛型,我们将以如下声明结束:

@Inject
private CityAutocompleteDataBean<ArrayList<String>>;
@Inject
private WrParamsDataBean<HashMap<String, WrData>>;

相对于

@Inject
private CityAutocompleteDataBean;
@Inject
private WrParamsDataBean;

使用<ArrayList<String>>的原因和 <HashMap<String, WrData>>当大多数开发人员看到这样的代码行时,他们会逃避。考虑到我们的起点和用途,我也觉得它很丑陋。

尽管如此,这还是按照我的要求工作,谢谢 Jesper。

最佳答案

您可以使用以下语法来完成:

public abstract class AbstractCachedSupport<T extends Serializable> {
// ...
}

public class CachedMap<T extends Map<String, Integer> & Serializable>
extends AbstractCachedSupport<T> {
// ...
}

这意味着类型 T必须实现 Map<String, Integer>还有Serializable .

然后你可以使用CachedMap具有特定的 Map实现 Serializable 的实现:

CachedMap<HashMap<String, Integer>> cachedMap = new CachedMap<>();

关于Java 泛型和可序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29879326/

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