gpt4 book ai didi

java - 必须在列表中使用的参数的通用方法中未经检查的强制转换警告

转载 作者:行者123 更新时间:2023-11-30 04:14:29 26 4
gpt4 key购买 nike

在下面的代码中,类型参数D可以是 List<Byte>List<List<Byte>> (它是 Fields<?, ?, D> 接口(interface)中的第三个通用参数,但我仍然可以在那里省略它 - 但它也存在于方法的返回类型中)。似乎找不到一种方法来告诉编译器这一点 - get Unchecked cast标记为 //* 的行中出现警告:

public static <D, K, T extends Enum<T> & Fields<?, ?, D>> List<EnumMap<T, D>> 
getEntries(InputStream is, Class<T> fields) throws IOException {
final List<List<Byte>> entries = new ArrayList<List<Byte>>();
// populate "entries"
final boolean hasLists = hasLists(fields);
List<K> daBytes;
if (hasLists) {
daBytes = (List<K>) new ArrayList<EnumMap<T, List<List<Byte>>>>(); //*
} else {
daBytes = (List<K>) new ArrayList<EnumMap<T, List<Byte>>>(); //*
}
final int numOfEntries = entries.size();
for (int currentEntry = 0; currentEntry < numOfEntries; ++currentEntry) {
// add an element in daBytes for this currentEntry
if (hasLists) {
daBytes.add((K) new EnumMap<T, List<List<Byte>>>(fields)); //*
} else {
daBytes.add((K) new EnumMap<T, List<Byte>>(fields)); //*
}
for (T daField : fields.getEnumConstants()) {
List<Byte> field = new ArrayList<Byte>();
// populate "field"
D map = (D) daBytes.get(currentEntry);
if (hasLists) {
List<List<Byte>> fieldEntries = new ArrayList<List<Byte>>();
// populate "fieldEntries"
((EnumMap<T, List<List<Byte>>>) map).put(daField,
fieldEntries); //*
} else {
((EnumMap<T, List<Byte>>) map).put(daField, field); //*
}
}
}
return (List<EnumMap<T, D>>) daBytes; //*
}

如果hasLists是假的那么我需要 D 是 List<Byte>否则 List<List<Byte>>daList变量是 List<EnumMap<T, D>> 。现在(对我来说)定义:

List<EnumMap<T, D>> daBytes;

但是一旦我这样做并改变:

if (hasLists) {
daBytes = (List<EnumMap<T, D>>) new ArrayList<EnumMap<T, List<List<Byte>>>>();
}

我收到错误:

Cannot cast from ArrayList<EnumMap<T,List<List<Byte>>>> to List<EnumMap<T,D>>

一直在兜圈子,让daBytes成为一个对象,一个List<?>等等,但总是使用直接强制转换或通用强制转换,从而导致警告。必须有一种方法可以干净地编译而不进行强制转换

最佳答案

我做了一些重构,按照其他海报的建议提取了“方法对象”。这是所谓的“策略类”设计模式的一个实例。

无论你在哪里检查hasLists,我都会引入一个抽象方法。事实证明,您不再需要 K 类型参数。

代码在顶部产生一个未经检查的警告,我在其中检查了 hasLists 以选择抽象类的实现。

public static <X, T extends Enum<T> & Fields<?, ?, List<X>>>
List<EnumMap<T, List<X>>> getEntries(InputStream is, Class<T> fields) throws IOException {
final List<List<Byte>> entries = new ArrayList<List<Byte>>();
// populate "entries"

FieldsStrategy<X, T> strategy = selectStrategy(fields);
return strategy.getEntries(entries);
}

private static <X, T extends Enum<T> & Fields<?, ?, List<X>>>
FieldsStrategy<X, T> selectStrategy(Class<T> fields) {
final boolean hasLists = hasLists(fields);
return hasLists
? (FieldsStrategy<X, T>) new ByteListFieldsStrategy(fields) //* this is the only unchecked warning
: (FieldsStrategy<X, T>) new ByteFieldsStrategy(fields); //* this is the only unchecked warning
}

private abstract static class FieldsStrategy<X, T extends Enum<T> & Fields<?, ?, List<X>>> {
private Class<T> fields;

public FieldsStrategy(Class<T> fields) {
this.fields = fields;
}

public List<EnumMap<T, List<X>>> getEntries(List<List<Byte>> entries) {

List<EnumMap<T, List<X>>> daBytes = new ArrayList<EnumMap<T, List<X>>>();
final int numOfEntries = entries.size();
for (int currentEntry = 0; currentEntry < numOfEntries; ++currentEntry) {
// add an element in daBytes for this currentEntry
daBytes.add(new EnumMap<T, List<X>>(fields));
for (T daField : fields.getEnumConstants()) {
EnumMap<T, List<X>> map = daBytes.get(currentEntry);
map.put(daField, getFieldData(daField));
}
}
return daBytes;
}

protected abstract List<X> getFieldData(T daField);

}

public static class ByteFieldsStrategy<T extends Enum<T> & Fields<?, ?, List<Byte>>>
extends FieldsStrategy<Byte, T> {
public ByteFieldsStrategy(Class<T> fields) {
super(fields);
}

protected List<Byte> getFieldData(T daField) {
ArrayList<Byte> field = new ArrayList<Byte>();
// populate "field"
return field;
}
}

public static class ByteListFieldsStrategy<T extends Enum<T> & Fields<?, ?, List<List<Byte>>>>
extends FieldsStrategy<List<Byte>, T> {
public ByteListFieldsStrategy(Class<T> fields) {
super(fields);
}

protected List<List<Byte>> getFieldData(T daField) {
List<List<Byte>> fieldEntries = new ArrayList<List<Byte>>();
// populate "fieldEntries"
return fieldEntries;
}
}

您可能可以通过移动 hasLists() 逻辑和开关来删除唯一剩余的未检查警告,以选择要使用哪个策略类到 Fields 接口(interface)并在enum 类。

更新:以下是 selectStrategyFields 的更新定义,不会引发任何警告:

public static interface Fields<T extends Enum<T> & Fields<T, D, K>, D extends Data, K> {
// ....

GetEntries<K, T> selectStrategy();
}

private static <K, T extends Enum<T> & Fields<T, ?, K>>
GetEntries<K, T> selectStrategy(Class<T> fields) {
for (T field : fields.getEnumConstants()) {
return field.selectStrategy();
}
throw new IllegalArgumentException("Enum type has no instances: " + fields);
}

您需要在 enum 类型中实现 selectStrategy() 并返回适当的 GetByteEntriesGetByteListEntries .

您现在可以删除 hasLists()

关于java - 必须在列表中使用的参数的通用方法中未经检查的强制转换警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18749426/

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