我正在使用类似于这个的异构容器.我可以轻松地从容器中放置和接收对象:
Favorites f = new Favorites();
f.putFavorite(String.class, "Java");
String someString = f.getFavorite(String.class);
Run Code Online (Sandbox Code Playgroud)
但似乎没有简单的方法来迭代这样的容器.我可以keySet()
在Favorites
类中添加一个方法,只需返回内部Map
对象的键集:
public Set<Class<?>> keySet() {
return favorites.keySet();
}
Run Code Online (Sandbox Code Playgroud)
现在,我想遍历键,使用键来获取关联的值,并在接收的对象上调用一些方法:
for (Class<?> klass : f.keySet()) {
// f.getFavorite(klass).<SOME_METHOD_SPECIFIC_TO_THE_CLASS-KEY>
}
Run Code Online (Sandbox Code Playgroud)
我以为我可以通过调用来访问容器中保存的对象的方法klass.cast(f.getFavorite(klass)).SOME_METHOD()
,但它也不起作用(意思是,我不能访问任何方法,除了Object
相关的方法).
让我们说,在我的用例中,我想检查我迭代的所有这些对象的接口,并相应地对检测到的接口采取行动.我们还假设我可能有几十个不同类的对象,并且它们都实现了三个接口之一.
我能想到的唯一解决方案是用几十个isinstance
检查填充我的代码,但我更喜欢一种不那么麻烦的方法(即检查给定对象是否实现了三个接口之一).
通过尝试在每个条目上调用特定方法,您基本上是说您比编译器更清楚,并且您知道每个条目都有特定的超类.
如果你知道的话,你可以使用Class#asSubclass
输入klass
为Class<? extends KnownSuper>
使getFavorite
然后将返回的一个子类KnownSuper
(并因此暴露方法):
Class<KnownSuper> superClass = KnownSuper.class; //class with callMethod()
for (Class<?> klass : f.keySet()) {
f.getFavorite(klass.asSubClass(superClass)).callMethod()
}
Run Code Online (Sandbox Code Playgroud)
但是,如果其中一个键类没有扩展,这显然会产生运行时异常KnownSuper
.因此,如果上述内容是安全的,您应该将异构容器参数化为仅接受从一开始就扩展的关键类KnownSuper
.
如果不是所有条目将是这种类型的,你也可以先检查一下,如果关键是迭代时适用:
Class<KnownSuper> superClass = KnownSuper.class; //class with callMethod()
for (Class<?> klass : f.keySet()) {
if (superClass.isAssignableFrom(klass)) {
f.getFavorite(klass.asSubClass(superClass)).callMethod()
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
172 次 |
最近记录: |