Java:如何推断嵌套泛型类型

3

Suppose I have class:

public interface ObjectWithId<T> {
    T getId();

    void setId(T id);
}

public class BaseDBObject<T> implements ObjectWithId<T> {
    // Common fields:
    private T id;
    private String createdBy;
...
}

还有一个具体的例子:

public class ConstituentEntity extends BaseDBObject<Integer> {
...
}

然后我创建了一些服务,也接受一个泛型参数之一? extends BaseDBObject,并且在某些方法中应该使用适当类型的id。现在它是用双重泛型实现的:

abstract public class BaseService<IdT,T extends BaseDBObject<IdT>> {
    public T getById(IdT id){
        return getDao().getById(id);
    }
}

public class ConstituentEntityService extends BaseService<Integer, ConstituentEntity>{
...
}

但再看一下最后一个定义。我已知道ConstituentEntity的主键是Integer,所以我认为再为服务提供该类型可能有些不美观。

我正在寻找写下一条语句的可能性:

abstract public class BaseService<T extends BaseDBObject> {
    public T getById(??T.T?? id){
        return getDao().getById(id);
    }
}

在 C++ 中,我们有 typenametypedef 用于这种情况,具有复杂但强大的元编程功能。Java 中是否有类似的功能?

也许不是最好的评论,但是:通常情况下,Java泛型是无法避免的丑陋。你只能忍受它们。我会像你的“双重泛型”方式一样做。 - Andy Turner
1个回答

2

我想,这是不可能的。如果你有许多使用Integer作为T的服务,那么你可以定义中间类:

public abstract class IntegerService<S extends BaseDBObject<Integer>> 
                                  extends BaseService<Integer, S>{
    ...
}

使用public class ConstituentEntityService extends IntegerService<ConstituentEntity>。但是如果使用多种不同的T类型,这种方法可能会不合适。


这可能是解决问题的(丑陋)变通方法。除此之外,它有两种通用类型,将隐藏在下一个层次结构中。同时它也有一些缺点。首先(你提到的)- 为任何类型创建中间类。其次,它只是实现的类,看起来像垃圾。最后,无论在哪里使用,该数字都会爆炸式增加(不仅服务需要它,还有验证器、助手等)。 - Hubbitus
@Hubbitus,这就是为什么我在回答中以“不可能”的方式开始的原因。我也不喜欢我的解决方案。 - Tagir Valeev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接