我有一个类根据消息的类将传入的消息映射到匹配的阅读器.所有消息类型都实现接口消息.读者在mapper类中注册,说明它将能够处理哪些消息类型.这些信息需要以某种方式存储在消息阅读器中,我的方法是private final
从构造函数中设置一个数组.
现在,似乎我对泛型和/或数组有一些误解,我似乎无法弄清楚,请参阅下面的代码.它是什么?
public class HttpGetMessageReader implements IMessageReader {
// gives a warning because the type parameter is missing
// also, I actually want to be more restrictive than that
//
// private final Class[] _rgAccepted;
// works here, but see below
private final Class<? extends IMessage>[] _rgAccepted;
public HttpGetMessageReader()
{
// works here, but see above
// this._rgAccepted = new Class[1];
// gives the error "Can't create a generic array of Class<? extends IMessage>"
this._rgAccepted = new Class<? extends IMessage>[1];
this._rgAccepted[0] = HttpGetMessage.class;
}
}
Run Code Online (Sandbox Code Playgroud)
ETA:
正如cletus正确指出的那样,最基本的Google搜索显示Java不允许通用数组.对于给出的示例我肯定理解这一点(比如E[] arr = new E[8]
,哪里E
是周围类的类型参数).但为什么new Class[n]
允许?那么"适当的"(或者至少是常见的)方式是什么呢?
cle*_*tus 30
Java不允许通用数组.Java Generics FAQ中的更多信息.
要回答您的问题,只需使用List(可能是ArrayList)而不是数组.
Java理论和实践中可以找到更多解释:泛型陷阱:
泛型不是协变的
虽然您可能会发现将集合视为数组的抽象是有帮助的,但它们具有集合不具有的一些特殊属性.Java语言中的数组是协变的 - 这意味着如果Integer扩展Number(它确实如此),那么不仅是
Integer
一个数字,而且Integer[]
也是一个Number[]
,你可以自由地传递或分配Integer[]
一个Number[]
被调用的地方对于.(更正式,如果Number
是的超类型Integer
,则Number[]
是一个超类型Integer[]
.)你可能会认为同样是泛型类型也是如此-这List<Number>
是一个超List<Integer>
,并且您可以通过一个List<Integer>
其中List<Number>
的预期.不幸的是,它没有那种方式.事实证明它有一个很好的理由它不会那样工作:它会破坏应该提供的类型安全仿制药.想象一下,你可以指定
List<Integer>
一个List<Number>
.然后,下面的代码将允许您将不属于的内容Integer
放入List<Integer>
:Run Code Online (Sandbox Code Playgroud)List<Integer> li = new ArrayList<Integer>(); List<Number> ln = li; // illegal ln.add(new Float(3.1415));
因为ln是a
List<Number>
,添加Float
它似乎是完全合法的.但是如果ln与li混淆,那么它将破坏li定义中隐含的类型安全承诺 - 它是一个整数列表,这就是泛型类型不能协变的原因.
归档时间: |
|
查看次数: |
24565 次 |
最近记录: |