代码之家  ›  专栏  ›  技术社区  ›  Ragesh

Java中的泛型与反射

  •  2
  • Ragesh  · 技术社区  · 16 年前

    这可能是一个非常基本的问题,但我对Java中的泛型很陌生,我很难用C语言的方式来改变我的思维过程,所以请容忍我。

    我试图在Java中构建一个通用的知识库。我创建了一个像这样的iRepository接口:

    public interface IRepository<T extends IEntity>
    

    以及一个像这样的存储库类:

    public class Repository<T extends IEntity> implements IRepository<T>
    

    现在,从我的知识库类的构造函数中,我希望能够“神化”T的确切类型。例如,如果我实例化了这样的知识库:

    IRepository<MyClass> repo = new Repository<MyClass>();
    

    我想知道T实际上是我的课。在C语言中,这是微不足道的,但显然泛型在Java中是完全不同的动物,我似乎找不到任何能帮助我做到这一点的东西。

    3 回复  |  直到 16 年前
        1
  •  5
  •   Bozho    16 年前

    爪哇使用 type erasure ,因此特定信息在运行时丢失-您只知道此类型是泛型的,而不是在编译时提供的特定参数。

        2
  •  2
  •   Jorn    16 年前

    您总是可以在构造函数中添加T的实际类型,如下所示:

    public class Repository<T> implements IRepository<T>
      public Repository(Class<T> type) {
      }
    }
    

    像例示一样

    IRepository<MyClass> repo = new Repository<MyClass>(MyClass.class);
    
        3
  •  0
  •   Joe    16 年前

    我做了一些类似的工作(也用于实现存储库/注册表模式),通过一些工作,您可以实际找到类型。但是请注意,我不是用接口,而是用一个基类来完成这项工作,而且还要注意,要得到一个有效的解决方案,需要进行一些尝试和错误。这段代码是在Sun JVM上运行的,所以我可能无意中发现了一个特定于JVM的领域。

    另外-正如另一条评论所提到的,仅仅因为你能做到这一点,并不意味着你必须做到:)

    import java.lang.reflect.ParameterizedType;
    ...
    public static Class<?> type(Object target) {
        Class base = target.getClass();
        while (base != null) {
            Object gsuper = base.getGenericSuperclass();
            if (gsuper != null && gsuper instanceof ParameterizedType) {
                Object o = ((ParameterizedType) gsuper).getActualTypeArguments()[0];
                if (o instanceof Class) {
                    return (Class<?>) o;
                }
            }
            base = base.getSuperclass();
        }
    
        return null;
    }
    

    我在我的baserepository类中使用了这个,比如:

    Class<?> type = type(SomeRepository);
    

    在哪里?

    public class SomeRepository extends Repository<MyEntity> {
    ... 
    }