Java 泛型:类型转换问题 (ClassCastException)
我无法弄清楚如何正确地将 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 对象?
提前致谢!
I'm having trouble figuring out how to properly cast a generic object in java to a type that extends the generic object.
For example, say I some setup like the following:
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();
}
}
}
Running code similar to the above consistently throws a ClassCastException, the likes of which I do not fully understand. Any assitence for how to correctly set up a scenario similar to the above would be appreciated! Namely, how might I properly cast the the SomeCustomMap object that is returned from the params.getSubSet(...) method back to a Parameters object?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的问题是 getSubSet 返回的子集是实例 SomeCustomMap 而不是参数。
这个问题不涉及泛型。如果您不使用泛型,您也会遇到同样的问题。
我不知道如何创建子集的实例,但也许您可以使用模板设计模式和一些泛型来解决您的问题。
Your Problem is that the Subset returned by getSubSet is a of instance SomeCustomMap and not of Parameters.
This problem does not deal with generics. You will get the same problem if you did not use generics.
I don't know how you create an instance of subset but maybe you could use the template desing pattern and some generics to fix your problem.
你可以尝试这样的事情:
创作看起来有点有趣 - 随意将其更改为你想要的任何内容:)
作为奖励,你不需要投射:)
You can try something like this:
creation looks a little funny - feel free to change it to whatever you want :)
As a bonus you will not need to cast :)
尽管我已经评论要求提供更多信息,但根据您迄今为止发布的内容,我认为
getSubSet
正在构造一个SomeCustomMap
来返回(使用new SomeCustomMap
) 某处。如果您没有重写Parameters
中的getSubSet
,则Parameters.getSubset
将返回一个SomeCustomMap
(基类),而不是Parameters
,因此您对Parameters
的类型转换失败。(热点提示,如果您重写
Parameters
类中的getSubSet
,则可以将返回类型更改为Parameters
并避免类型转换。)Though I've commented asking for more information, based on what you've posted so far, I think
getSubSet
is constructing aSomeCustomMap
to return (withnew SomeCustomMap
) somewhere. If you don't overridegetSubSet
inParameters
, thenParameters.getSubset
will return aSomeCustomMap
(the base class), not aParameters
, so your typecast toParameters
fails.(Hot tip, if you override
getSubSet
in theParameters
class, you can change the return type toParameters
and avoid the typecast.)泛型本质上与转换没有任何关系(除了由于擦除的性质,在转换期间无法检查泛型参数)。
如果在这种情况下您收到
ClassCastException
,则意味着返回的对象实际上不是Parameters
的实例。在进行转换之前,尝试调用并查看子集的实际运行时类是什么。问题很可能出在其他地方,因为您期望子集是一个Parameters对象在运行时几乎肯定是不正确的——它是一个
SomeCustomMap
或其一些其他子类。Generics don't inherently have anything to do with casting (save that due to the nature of erasure, generic parameters cannot be checked during a cast).
If you're getting a
ClassCastException
in this case, it means that the object returned really is not an instance ofParameters
. Just before you cast, try callingand see what the actual run-time class of the subset is. Chances are the problem lies elsewhere, as your expectation that the subset is a Parameters object is almost certainly not correct at runtime - it's a
SomeCustomMap
or some other subclass thereof.正如其他人所解释的,问题在于您在 getSubSet() 中构造的实际对象不是Parameters 的实例。
这是一种可能的解决方法。我不喜欢它,但它是一种在
SomeCustomMap
中声明方法但可以为任何子类正确键入其返回值的方法。As others have explained, the issue is that the actual object you are constructing in
getSubSet()
is not an instance ofParameters
.Here's one possible workaround. I don't love it, but it is a way to declare the method in
SomeCustomMap
but have its return value be typed correctly for any subclass.