gpt4 book ai didi

java - 类型安全的通用集合生成器/容器

转载 作者:搜寻专家 更新时间:2023-11-01 02:49:36 25 4
gpt4 key购买 nike

在我的方法 readList 中,我想构建一个用户定义类型的 java.util.List(具体列表类型是一个参数)。但是,我不想将 readList 限制为 ArrayListLinkedList;用户可以提供他自己的 java.util.List 实现。如果可能,该方法还可能缓存列表,因此该方法需要返回列表。我尝试了一些东西。以下哪一项是您认为的“最佳”API,或者还有其他更好的 API?

以下编译,但我收到编译器警告:“类型安全:类型 ArrayList 的表达式需要未经检查的转换以符合 ArrayList”,所以这不是一个好的解决方案:

void classParameter() {
ArrayList<String> a = readList(ArrayList.class);
LinkedList<String> b = readList(LinkedList.class);
}

<X, T extends List<X>> T readList(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

以下编译,但我仍然收到编译器警告,而且它实际上没有按预期工作:

void classTypeParameters() {
ArrayList<String> a = readList(ArrayList.class, String.class);
LinkedList<String> b = readList(LinkedList.class, Integer.class);
}

<T extends List<X>, X> T readList(Class<T> clazz, Class<X> type) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

以下作品,是我个人最喜欢的。它检查列表类型。有点危险的是有人可能会错误地忘记分配结果。这可以通过将 readList 重命名为 readListWithTemplate 左右来解决,这将更明显地使用返回值。它类似于 List.toArray(T[] a):

void template() {
ArrayList<String> a = readList(new ArrayList<String>());
LinkedList<String> b = readList(new LinkedList<String>());
// wrong usage:
List<String> c = new LinkedList<String>();
readList(c);
}

@SuppressWarnings("unchecked")
<X, T extends List<X>> T readList(T template) {
try {
return (T) template.getClass().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

“ super token 类型”也可以,但可能有点难以理解对于不熟悉此模式的开发人员,以及在 Eclipse 中我收到警告“应记录空 block ”,我想避免这种情况:

void superTypeToken() {
ArrayList<String> a = readList(new ListType<ArrayList<String>>() {});
LinkedList<String> b = readList(new ListType<LinkedList<String>>() {});
}

abstract static class ListType<X extends List<?>> {
// super type token class
}

@SuppressWarnings("unchecked")
<X, T extends List<X>> T readList(ListType<T> t) {
try {
Type type = t.getClass().getGenericSuperclass();
if (!(type instanceof ParameterizedType)) {
throw new IllegalArgumentException("Missing type parameters");
}
ParameterizedType pt = (ParameterizedType) type;
type = pt.getActualTypeArguments()[0];
pt = (ParameterizedType) type;
Class<?> listClass = (Class<?>) pt.getRawType();
return (T) listClass.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

你更喜欢哪一个?或者有更好的解决方案吗?

最佳答案

我可能会委托(delegate)给另一个构建器类。一个只知道如何创建新列表的小类(class)。它提供了更好的运行时安全性,因为它不依赖于给定类具有默认构造函数的假设。对于列表可能没那么有用,因为我们应该始终能够创建一个空列表,但对于其他类型的类更重要。

例如。

public interface EmptyListBuilder {

public <E> List<E> newList();

public static final EmptyListBuilder ARRAY_LIST_BUILDER =
new EmptyListBuilder() {

public <E> List<E> newList() {
return new ArrayList<E>();
}
};
}

如静态字段所示,您还可以为一些标准类提供默认实现。

像这样使用类:

<T> List<T> readList(EmptyListBuilder builder) {
List<T> list = builder.newList();
// read in elements
return list;
}

您无法准确知道您拥有的列表类型,但这是一个问题,听起来您正在尝试做一些有点奇怪的事情。

关于java - 类型安全的通用集合生成器/容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13916209/

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