2015-01-09 93 views
0

C++模板类似的功能在我的节目,我有下面的类层次结构:需要在Java中

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++,所有EffectListN类都可以通过1个模板轻松生成,但AFAIK(对于Java来说相当新颖),Java泛型无法完成这项工作。

有什么建议吗?

+0

是[这个问题](http://stackoverflow.com/questions/1854335/how-to-create-a-java-class-similar-to-a-c-template-class)有关吗? – jdv

回答

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之间共享只有一个变量(因为它的下方仅只是一个只有类编译时检查添加)。

+0

谢谢,您的评论帮助我意识到静态字段是问题的本质。我最终改变了架构,使我不再需要实例化大量的EffectListN类,而只是每个类的一个实例。这让我摆脱了静态领域。 – Leszek

1

我不知道如何用C++来完成它,但是关闭你的描述,不,Java泛型将无法处理这个问题。

其中之一,您有static字段取决于EffectN类型中定义的其他static字段。 Java中没有任何内容设置一个类型应该有一个static字段的限制。你不会是能够动态地设置

public static final N = SomeEffect.NAME; 

其次,因为类型擦除,你不会是能够做到

public EffectList2 
{ 
    mEffect = new SomeEffect(); // assuming SomeEffect is the type parameter 
} 

你需要在Class实例,并使用反射来传递实例化这种类型。