gpt4 book ai didi

java - 未检查的从对象到列表的转换

转载 作者:行者123 更新时间:2023-11-30 03:00:52 26 4
gpt4 key购买 nike

我正在尝试扩展已发布问题的解决方案 here .

那里共享的castList方法非常适合非泛型类型。

public static <T> List<T> castList(Object obj, Class<T> clazz)
{
List<T> result = new ArrayList<T>();
if(obj instanceof List<?>)
{
for (Object o : (List<?>) obj)
{
result.add(clazz.cast(o));
}
return result;
}
return null;
}

我们遇到的问题是,当返回类型不是简单的字符串列表(如字符串列表)时,而是当列表本身是另一个泛型(如 map 列表)时,尝试使用相同的想法。

List<Map<String, Object>> list = (List<Map<String, Object>>) out.get("o_cursor");

尝试按如下方式使用castList会产生类型不匹配:无法从List转换为List >。有没有办法扩展castList来做到这一点?

List<Map<String, Object>> list = castList(out.get("o_cursor"), Map.class);

我尝试了特定于 map 列表的修改版本,但仍然收到错误“方法castMapList(Object, Class >)不适用于参数 (Object, Class )”,这似乎是同一错误的不同风格。

public static <K, V> List<Map<K, V>> castMapList(Object object, Class<Map<K, V>> clazz) {        
if (object instanceof List<?>) {
List <Map<K, V>> result = new ArrayList<Map<K, V>>();

for (Object o: (List<?>) object) {
result.add(clazz.cast(o));
}

return result;
}

return null;
}

最佳答案

由于删除,有:

  1. 不可能有 Class<Map<K, V>> .
  2. 没有内置方法可以在运行时检查每个特定的 Map有一些特殊的KV .

即:

  1. 正如您所发现的,每个泛型类都有相应的原始类型 Class对象,例如Map.classClass<Map> .
  2. 类似于 obj instanceof Map<K, V>是一个编译器错误并且 Class对象不会检查通用参数,例如isInstancecast .

重要的是,如果不做一些额外的工作,您就无法在运行时验证泛型。

您仍然可以围绕它进行编程,具体取决于您正在做什么。例如,一种简单的方法就是重建每个 Map ,与重建 List 的方式相同:

static <K, V> List<Map<K, V>> castMapList(
Object obj, Class<K> keyType, Class<V> valueType) {
if (obj instanceof List<?>) {
List<Map<K, V>> result = new ArrayList<>();

for (Object element : (List<?>) obj) {
if (element instanceof Map<?, ?>) {
Map<K, V> map = new HashMap<>();

for (Map.Entry<?, ?> entry : (Map<?, ?>) element) {
map.put(keyType.cast(entry.getKey()),
valueType.cast(entry.getValue());
}

result.add(map);
} else {
// do something that you want?
// personally I would throw ClassCastExceptions
// but you seem to be returning null
}
}

return result;
}
return null;
}

此外,例如,看起来您似乎正在进行某种反序列化,您可以烘焙 Class直接进入Map被序列化:

public class MyCheckedMap<K, V>
extends SomeMapImplementation<K, V>
implements Serializable {
private static final long serialVersionUID = 1L;
private final Class<K> keyType;
private final Class<V> valueType;

public MyCheckedMap(Class<K> keyType, Class<V> valueType) {
this.keyType = Objects.requireNonNull(keyType);
this.valueType = Objects.requireNonNull(valueType);
}

@SuppressWarnings("unchecked")
public static <K, V> MyCheckedMap<K, V> cast(
Object obj, Class<K> keyType, Class<V> valueType) {
if (!(obj instanceof MyCheckedMap<?, ?>))
throw new ClassCastException(obj.getClass().toString());

MyCheckedMap<?, ?> map = (MyCheckedMap<?, ?>) obj;
validate(keyType, map.keyType);
validate(valueType, map.valueType);

return (MyCheckedMap<K, V>) obj;
}

private static void validate(Class<?> lhs, Class<?> rhs) {
if (lhs == rhs)
return;
throw new ClassCastException(String.format("%s != %s", lhs, rhs));
}
}

您必须为每个 List 编写一些样板代码, Map等等,但可能不会比您看起来做的多得多。

还有一些其他方法可以解决此类问题,例如 Neal Gafter 的 Super Type Tokens和 Guava 的 TypeToken ,这是 Neal Gafter 想法的衍生。这些本质上使用反射来实现类似 MyCheckedMap 的东西.

关于java - 未检查的从对象到列表的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36021925/

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