5

我已经使用 Java 很长一段时间了,但有些事情对我来说仍然不是很清楚,尤其是在泛型方面......

事情是这样的:我正在使用这个Search类(有关详细信息,请参见此处),其构造如下:

public Search(Class<?> searchClass) {...}

此外,我有一个参数化的通用包装器,如下所示:

public class HibernateSearch<E> extends Search implements Serializable {
    public HibernateSearch(Class<E> entityClass) {
        super(entityClass);
    }
    // ... omitted for brevity
}

现在,我需要的是以下内容:我想创建一个参数化的类,它包含这个类作为它的字段,例如

public class BaseSelectorComposer<T> extends SelectorComposer<Window> {

    private HibernateSearch<T> searchObject;
    ...
    @Override
    public void doAfterCompose(Window comp) throws Exception {
        super.doAfterCompose(comp);
        this.searchObject =
             new HibernateSearchObject<T>( now what...??? );
        ...
    }
    ...
}

我认为我面临的问题从给定的例子中是显而易见的。
有人可以建议在这里可以做些什么,或者一些替代方案吗?

4

2 回答 2

5

最简单的方法是将责任转嫁给实际实例化和使用实例的人BaseSelectorComposer,即:

public class BaseSelectorComposer<T> extends SelectorComposer<Window> {

    private HibernateSearch<T> searchObject;
    private final Class<T> theType;

    public BaseSelectorComposer(Class<T> token) {
        theType = token;
    }

    ...
    @Override
    public void doAfterCompose(Window comp) throws Exception {
        super.doAfterCompose(comp);
        this.searchObject = new HibernateSearchObject<T>(theType);
        ...
    }
    ...
}

如果你BaseSelectorComposer是一个抽象子类,它只会像这样使用

class IntSelectorComposer extends BaseSelectorComposer<Integer> {
    ...
}

即,作为“绑定”类型参数的类的基类,有一些方法可以通过反射获取类型信息(尽管这非常难看,因为这在 API 恕我直言中并没有得到很好的支持)。

于 2013-06-06T13:15:36.477 回答
1

通常,这是一个难以解决的方案。来自 .NET 背景,我个人发现很少有可以解决这个问题的情况,因为 Java 不支持静态泛型类型解析(例如在 .NET 中可以使用typeof(T))。

为了解决这个问题,我建议您找到一种方法来获取外部类或该类的实例。doAfterCompose一种可能的解决方案是通过以下方式之一更改方法:

@Override
public void doAfterCompose(Window comp, Class<?> entityClass) throws Exception {
    super.doAfterCompose(comp);
    this.searchObject =
         new HibernateSearchObject<T>(entityClass);
    ...
}

-或者-

@Override
public void doAfterCompose(Window comp, SomeEntity entity) throws Exception {
    super.doAfterCompose(comp);
    this.searchObject =
         new HibernateSearchObject<T>(entity.getClass());
    ...
}

如果您无法修改方法签名(我看到它是一个覆盖),请尝试使用BaseSelectorComposer<T>将保存所需Class<?>实例的类的成员。

public class BaseSelectorComposer<T> extends SelectorComposer<Window> {
    private Class<?> entityClass;

    public BaseSelectorComposer<T>(Class<?> entityClasss) {
        this.entityClass = entityClass;
    }

   ....
    @Override
    public void doAfterCompose(Window comp) throws Exception {
        super.doAfterCompose(comp);
        this.searchObject =
            new HibernateSearchObject<T>(this.entityClass);
       ...
    }
}
于 2013-06-06T13:15:27.403 回答