2015-10-05 50 views
0

您好我目前正在研究一些遗留的代码,我已经继承,我需要将一种类型转换为另一种类型来结束我的重构。 我遇到的问题是,我有一个返回Class<AbstractSuperClass>一个对象,但我需要将其转换成AbstractSuperClass //(concrete object although abstract)如何将通用类型转换为Java中的具体类型

我试图做的是使用枚举常量来表示一个抽象类的具体子类,然后使用实例化对象的常量。但我所有的铸造尝试迄今都失败了。

如果有人能够在这种情况下为正确的方向提供一些指针,那将是最有帮助的。

+5

'Class'对象不是'AbstractSuperClass'对象。铸造将永远不会工作。请说明你在做什么或试图做什么。 –

+0

嗨,谢谢你的回答,我试图做的是通过enum(ENUMVAL(baseClassFoo).class)返回Class ,如果我能成功地将此返回类型转换为我在其他类中的抽象类方法我可以消除大量冗余代码,并使用baseClassFoo中定义的算法,而不必使用动态调度来检查条件。 – JKT

+0

你问如何实例化一个类,因为它的'Class'对象? (通过反射?) –

回答

3

你的问题并不完全清楚。它看起来像你试图使用枚举常量来表示一个抽象类的具体子类,并且你希望能够使用这些常量来实例化对象。这是可能的:

public enum ConcreteClass { 

    CONCRETE1(Concrete1.class), 
    CONCRETE2(Concrete2.class); 

    private final Class<? extends AbstractClass> clazz; 

    private ConcreteClass(Class<? extends AbstractClass> clazz) { 
     this.clazz = clazz; 
    } 

    public AbstractClass instantiate() throws InstantiationException, IllegalAccessException { 
     return clazz.newInstance(); 
    } 
} 

用这个你可以做AbstractClass obj = ConcreteClass.CONCRETE2.instantiate();。您必须在try块中执行此操作,因为这些例外是已检查的例外情况。

就我个人而言,我不喜欢使用反射。我想用Supplier<AbstractClass>是更好的(需要Java 8):

public enum ConcreteClass { 

    CONCRETE1(Concrete1::new), 
    CONCRETE2(Concrete2::new); 

    private final Supplier<AbstractClass> supplier; 

    private ConcreteClass(Supplier<AbstractClass> supplier) { 
     this.supplier = supplier; 
    } 

    public AbstractClass instantiate(){ 
     return supplier.get(); 
    } 
} 

这种方法不使用反射,不涉及检查异常,而且是更普遍的,因为它可以与只具有静态类使用工厂方法和没有公共构造函数。

+0

没有通配符在第二个解决方案? :)但我同意,通配符是地狱。 – ZhongYu

+0

@ bayou.io我不认为通配符会在第二种解决方案中为您购买任何东西,而在第一个示例中,您需要它们进行编译。我是那些真正喜欢通配符的陌生人之一。 –

+1

嗯...是的,所有的枚举构造函数的调用网站都是已知的,因此没有通配符就没有问题了。我会[争论](http://bayou.io/draft/Wildcard_Case_Studies.html#Missing_Wildcards)通常可以省略通配符的真正原因是参数通常是lambda表达式或方法引用,java类型推断可以采用照顾适合的类型。 – ZhongYu

相关问题