cod*_*edd 9 java generics inheritance hashmap
我有以下测试用例无法从以下位置检索值Map:
package tests;
import java.util.HashMap;
import java.util.Map;
public class ClassTest {
interface A {}
interface B extends A {}
interface C extends A {}
class D implements B {}
class E implements C {}
public ClassTest() {
Map<Class<? extends A>, A> map = new HashMap<>();
A d = new D();
A e = new E();
map.put(d.getClass(), d);
map.put(e.getClass(), e);
System.out.println(B.class.getSimpleName() + ": " + map.get(B.class));
System.out.println(C.class.getSimpleName() + ": " + map.get(C.class));
}
public static void main(String[] args) {
new ClassTest();
}
}
Run Code Online (Sandbox Code Playgroud)
该预计产量为:
B: D
C: E
Run Code Online (Sandbox Code Playgroud)
在实际的输出是:
B: null
C: null
Run Code Online (Sandbox Code Playgroud)
根据我的理解,案例是"预期"失败因为B.class不等于D.class,即使Dclass是B接口的实现...因此map.get(...)无法找到关联键的实例值.(纠正我,如果我错了这一点.)上述希望的情况下,显示了意图的背后是什么我要完成和"精神".
有没有一个好的/优雅的替代方案,但也保留了我试图做的精神?
我正在更新代码以替换Class<T>用作类型标记的"开放集"的枚举类型,有点类似于Effective Java,2nd Ed.,Item 29.
正如@CKing在评论中所要求的那样,本书的部分内容引用了我的方法.
客户端
Class在设置和获取收藏夹时会显示一个对象.这是API:Run Code Online (Sandbox Code Playgroud)// Typesafe heterogeneous container pattern - API public class Favorites { public <T> void putFavorite(Class<T> type, T instance); public <T> T getFavorite(Class<T> type); }下面是行使一个示例程序
Favorites类,存储,检索和打印最喜欢的String,Integer和Class实例:Run Code Online (Sandbox Code Playgroud)// Typesafe heterogeneous container pattern - client public static void main(String[] args) { Favorites f = new Favorites(); f.putFavorite(String.class, "Java"); f.putFavorite(Integer.class, 0xcafebabe); f.putFavorite(Class.class, Favorites.class); String favoriteString = f.getFavorite(String.class); int favoriteInteger = f.getFavorite(Integer.class); Class<?> favoriteClass = f.getFavorite(Class.class); System.out.printf("%s %x %s%n", favoriteString, favoriteInteger, favoriteClass.getName()); }正如您所料,该程序打印出来
Java cafebabe Favorites.
请理解我知道这本书的例子是有效的,因为它使用了值的具体具体类(例如String.class,对于实际的String,而不是某些假设的派生类型String等)如上所述,这只是激发了我的方法,看看我的测试用例会工作,现在我正在寻找一个解决方案或替代方案,尊重我打算在测试用例上做的"精神".
也许不是那么优雅,但您可以使用反射来获取所有可分配的值Key.class:
System.out.println(B.class.getSimpleName() + ": " + getMapEntries(map, B.class));
System.out.println(C.class.getSimpleName() + ": " + getMapEntries(map, C.class));
....
private <T extends A> List<T> getMapEntries(Map<Class<? extends A>, A> map, Class<T> clazz) {
List<T> result = new ArrayList<>();
for (Map.Entry<Class<? extends A>, A> entry : map.entrySet()) {
if (clazz.isAssignableFrom(entry.getKey())) {
result.add((T) entry.getValue());
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1197 次 |
| 最近记录: |