我无法弄清楚如何将java中的通用对象正确地转换为扩展泛型对象的类型。
例如,假设我设置如下:
public class Parameters extends SomeCustomMap<String, String>
{
...
}
public class SomeCustomMap<K, V> implements Map<K, V>
{
public SomeCustomMap<K, V> getSubSet(...)
{
SomeCustomMap<K, V> subset;
...
return subset;
}
}
class ExampleApp
{
private void someMethod()
{
Parameters params;
Parameters paramsSubSet;
try
{
...
paramsSubSet = (Parameters) params.getSubSet(...);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
运行类似于上面的代码一直抛出ClassCastException,我不完全理解。如何正确设置类似于上面的场景的任何帮助将不胜感激!也就是说,我如何正确地将从params.getSubSet(...)方法返回的SomeCustomMap对象强制转换回Parameters对象?
提前致谢!
答案 0 :(得分:2)
你的问题是getSubSet返回的子集是SomeCustomMap的实例,而不是参数。
此问题不涉及泛型。如果你不使用泛型,你会遇到同样的问题。
我不知道你是如何创建子集的实例的,但也许你可以使用模板设计模式和一些泛型来解决你的问题。
答案 1 :(得分:1)
虽然我评论过要求提供更多信息,但根据您目前发布的内容,我认为getSubSet
正构建一个SomeCustomMap
来返回(new SomeCustomMap
)某处。如果您未覆盖getSubSet
中的Parameters
,则Parameters.getSubset
将返回SomeCustomMap
(基类),而不是Parameters
,因此您的类型转换为Parameters
失败。
(热门提示,如果您在getSubSet
类中覆盖Parameters
,则可以将返回类型更改为Parameters
并避免类型转换。)
答案 2 :(得分:1)
泛型本身与铸造没有任何关系(除了由于擦除的性质,在演员表中无法检查通用参数)。
如果您在这种情况下获得ClassCastException
,则意味着返回的对象确实不是Parameters
的实例。在演出之前,尝试调用
System.out.println(params.getSubSet(...).getClass());
并查看子集的实际运行时类。机会问题在于其他地方,因为您期望子集是一个Parameters对象在运行时几乎肯定是不正确的 - 它是SomeCustomMap
或其他其他子类。
答案 3 :(得分:1)
您可以尝试这样的事情:
public <T extends SomeCustomMap<K, V>> T getSubSet(...){
T subset = (T)this.clone();
subset.clear();
return subset;
}
创作看起来有点搞笑 - 随意将其更改为您想要的任何内容:)
作为奖励,你不需要施放:)
paramsSubSet = params.getSubSet(...)
答案 4 :(得分:0)
正如其他人所解释的那样,问题是您在getSubSet()
中构建的实际对象不是Parameters
的实例。
这是一种可行的解决方法。我不喜欢它,但它是一种在SomeCustomMap
中声明方法但是为任何子类正确键入其返回值的方法。
public static <T extends SomeCustomMap<K, V>> getSubSet(T fullSet)
{
T subset;
... (use fullSet instead of this)
return subset;
}