在我的程序中,我有以下类层次结构:
public abstract class Effect
{
// ...
}
public class Effect1 extends Effect
{
public static final NAME = "blah blah 1";
// ...
}
public class Effect2 extends Effect
{
public static final NAME = "blah blah 2";
// ...
}
(更多具有完全不同实现的EffectN类)。后来,我又使用了那些EffectN来获得另一类课程:
public abstract class EffectList
{
protected Effect mEffect;
// ...
}
public class EffectList1 extends EffectList
{
public static final N = Effect1.NAME;
public EffectList1
{
mEffect = new Effect1();
}
// ...
}
public class EffectList2 extends EffectList
{
public static final N = Effect2.NAME;
public EffectList2
{
mEffect = new Effect2();
}
// ...
}
(更多的EffectListN类,每个EffectN一个)。
现在,虽然EffectN确实有很多不同的实现,但所有的EffectListN都是(几乎)相同的 - 它们之间的唯一区别如上所示。
现在,如果这是C ++,只需1个模板就可以轻松生成所有的EffectListN类,但是AFAIK(对Java来说很新)Java泛型无法完成这项工作,是吗?
有什么建议吗?
答案 0 :(得分:1)
我不知道你将如何用C ++做到这一点,但是不用你的描述,不,Java泛型将无法处理这个问题。
例如,您有static
个字段,这些字段取决于static
类型中定义的其他EffectN
字段。 Java中没有任何内容设置类型应具有static
字段的限制。你将无法动态设置
public static final N = SomeEffect.NAME;
其次,由于类型擦除,你将无法做到
public EffectList2
{
mEffect = new SomeEffect(); // assuming SomeEffect is the type parameter
}
您需要传入Class
实例并使用反射来实例化此类型。
答案 1 :(得分:1)
您是否尝试创建调用构造函数的通用方法?如果是这样,只要所有实现都提供相同类型的参数,这可以通过反射完成,例如默认构造函数:
class EffectList<EffectType extends Effect> {
public EffectList(Class<EffectType> clazz) {
try {
mEffect = clazz.getConstructor().newInstance();
} catch (Exception ex) {
// suppressing Exceptions - in production code you should handle it better
throw new RuntimeException(ex);
}
// ...
}
// ...
}
然后像这样使用它:
EffectList<Effect1> effectList1 = new EffectList(Effect1.class);
EffectList<Effect2> effectList2 = new EffectList(Effect2.class);
然而,无法以这种方式处理静态字段 - 您可以做的最好是使其成为实例变量并通过反射获取值:
clazz.getDeclaredField("NAME").get(null); // null is used to obtain static fields
无法处理静态字段的原因是所有EffectLists中只有一个变量共享(因为只有一个类只添加了编译时检查)。