获取一个类的泛型类型以创建另一个泛型类

时间:2012-06-25 20:48:19

标签: java generics

我似乎已经让自己陷入了欢乐的转折。我有类似以下情况:

public class Parameter<T> {
   public Parameter(String value, Verifier<T> verif){
       //stuff, lots of stuff!
   }
}

public interface Verifier<T>{
   //definition
}

public enum StringVerif implements Verifiier<String>{
    INSTANCE;
    //some static functions on my singleton
}

public abstract class ParamFactory{
    private static ArrayDeque<Verifier<?>> verifList...
    ...
    for(Verifier<?> ver : verifList){
        if(ver.isapplicable(someData){
            //now I'm stuck!
        }
    }
}

简而言之,我需要做的是根据通过测试的Verifier的类型创建正确的类型化参数。例如对于Verifier我需要能够创建一个参数,对于Verifier我需要能够创建一个参数。然后,这些参数将被发送到另一个集合。从本质上讲,它是一个可扩展的工厂,带有验证器和处理器模块,可以根据需要解析不同类型的参数,功能非常强大。问题是我不仅要通过反射获得泛型类型,还要从这种类型创建泛型类型。

关于从哪里开始这样做的任何想法?自从我深入研究泛型

以来,已经有很长一段时间了

2 个答案:

答案 0 :(得分:0)

原来我一直在接近这个错误。正确的技术是每个Verifier负责调用构造函数,并且因为每个验证器已经知道它自己的类型,所以它只是几行。它有点打破了工厂的概念,除非你认为这些验证器真正成为工厂的一个组成部分

public interface Verifier<T>{
   //definition
   public Err buildParaList(String value, Single<Parameter<?>> output);
}

public enum StringVerif implements Verifiier<String>{
    INSTANCE;
    //some static functions on my singleton
    @Override
    public Err buildParaList(String value, Single<Parameter<?>> output){
        output.elem = new Parameter<String>(value, INSTANCE);
        return Err.success();
    }
}
public abstract class ParamFactory{
    private static ArrayDeque<Verifier<?>> verifList...
    ...
    for(Verifier<?> ver : verifList){
        if(ver.isapplicable(someData){
            Single<Parameter<?>> param = new Single<Parameter<?>>();
            Err e = ver.buildParameter(value, param);
            //checks
            paramList.add(param.elem);
        }
    }
}

确定我的实际用法比示例更复杂,但它仍然有效。我之前真的应该想到这一点,我想昨晚我不是那么警惕。感谢您的支持。

答案 1 :(得分:0)

扩展我之前关于HList的评论:(这对评论来说太大了,所以将其作为答案发布。)

我使用Scala作为代码示例,因为它对所讨论的想法有很好的支持。所有代码示例都在控制台中输入。

当您拥有类型为Dog的对象和另一个类型为Tiger的对象时,如果将它们放在同一个协变列表中,则生成的列表将具有List[Animal]类型{} {1}}是他们常见的超类型。原始类型丢失,因为此列表是同类的。请注意下面列出的推断类型:

Animal

同样,scala> class Animal defined class Animal scala> class Dog extends Animal defined class Dog scala> class Tiger extends Animal defined class Tiger scala> List(new Tiger, new Dog) res0: List[Animal] = List(Tiger@a32604, Dog@1150b68) Verifier[Int]放在单个同类列表中时会假定类型为Verifier[String]。 (在Scala中,Verifier[Any]类位于对象层次结构的顶部。)请参阅:

Any

如果要保留静态类型,并将其用于计算后者,则应使用异构列表。或者scala> class Verifier[+T](value: T) { | override def toString = "Verifier(" + value.toString + ")" | } defined class Verifier scala> List(new Verifier(6), new Verifier("hello")) res1: List[Verifier[Any]] = List(Verifier(6), Verifier(hello))

HList

以下是多态映射的工作原理:

scala> new Verifier(6) :: new Verifier("hello") :: HNil
res2: shapeless.::[Verifier[Int],shapeless.::[Verifier[java.lang.String],shapeless.HNil]] = Verifier(6) :: Verifier(hello) :: HNil

我们保留了类型参数,并使用给定的更高级别的函数对列表的每个元素执行操作。这给了我们scala> class Parameter[+T](value: String, verif: Verifier[T]) { | override def toString = "P(" + value + ", " + verif + ")" | } defined class Parameter scala> object mapper extends (Verifier ~> Parameter) { | def apply[A](v: Verifier[A]): Parameter[A] = new Parameter("k", v) | } defined module mapper scala> res2 map mapper res3: mapper.Out = P(k, Verifier(6)) :: P(k, Verifier(hello)) :: HNil HListParameter s,其中保留了正确的类型。

请注意,HList的概念可以用Java实现,但是您无法在结构上定义许多有用的操作。 Java的类型系统不具备它的能力。如果您有兴趣,Here是一篇关于该主题的精彩文章。

希望这在某些方面有所帮助。