我想动态更改方法的返回类型。例如,我有这样的代码:
class A {
}
class B extends A {
public void animate1() { }
public void animate2() { }
}
class C extends A {
public void animate3() { }
public void animate4() { }
}
class Registry {
private Map<String, A> mMap;
public <T> T get(String key) {
A data = mMap.get(key);
/*
* I would like to implement like this:
* if(data.getClass() == B.class)
* T = B;
* else if(data.getClass() == C.class)
* T = C;
*/
return (T) data;
}
public void put(String key, A data) {
mMap.put(key, data);
}
}
现在我可以这样做:
mRegistry.put("key_b", new B());
mRegistry.put("key_c", new C());
((B) mRegistry.get("key_b")).animate1();
((C) mRegistry.get("key_c")).animate4();
我想实现这样的代码(没有强制转换):
mRegistry.put("key_b", new B());
mRegistry.put("key_c", new C());
mRegistry.get("key_b").animate1();
mRegistry.get("key_c").animate4();
该方法可以在某些数据中更改其后续返回类型,类似于第一个代码(注释时)。 也许有人知道,如何以另一种方式解决这个问题,但是没有在类注册表外部强制转换?
答案 0 :(得分:2)
A类必须有animate1()和animate4()
class A {
void animate1() {
throw new UnsupportedOperationException();
}
void animate4() {
throw new UnsupportedOperationException();
}
}
所以这个编译因为get()方法返回A
mRegistry.get("key_b").animate1();
mRegistry.get("key_b").animate4();
答案 1 :(得分:1)
如果您知道密钥与类具有一对一的关系,也就是说,您知道存储的是X类型的实例但是您对保存特定实例感兴趣,则可以使用{{ 1}}令牌作为密钥:
Class
class Registry {
private Map<Class<? extends A>, A> mMap;
public <T extends A> T get(Class<T> key) {
A data = mMap.get(key);
return (T) data;
}
public void put(Class<? extends A> key, A data) {
mMap.put(key, data);
}
}
// Usages would look like:
reg.put(C.class, new C());
C myC = reg.get(C.class); // No cast required
方法还需要使用类标记而不是使用put
从值中提取类标记的原因有两个:
data.getClass()
,则可以执行class C1 extends C
,并且会在密钥reg.put(C.class, new C1());
下检索该对象。C.class
输入注册表(如果您想允许)。显然,特定的null
实现可能不允许它,并且如果您尝试使用不存在的键,它始终是返回的默认值。但是,它可能(或可能不是)在您的设计中很重要。