Why is it impossible to inject generic classes? [c

2019-02-17 00:37发布

I have a generic abstract template class. I thought if I create type-specific Producers, I could inject some DAO service directly in the generic class. But I can't.

Why? And how could I work around this?

abstract class MyView<T> {
    @Inject
    MyDao<T> dao;

    //some more template methods that make use of the dao
    void someMethod() {
        dao.use();
    }
}

class CustomerView extends MyView<Customer> {
    //javax.enterprise.inject.AmbiguousResolutionException: Ambigious resolution
}


class DaoManager {
    @Produces
    MyDao<Customer> getDaoCustomer() {
        return DaoFactory.make(Customer.class);
    }

    @Produces
    MyDao<Product> getDaoProduct() {
        return DaoFactory.make(Product.class);
    }
}

When I inject eg a @Inject MyDao<Customer> dao; it works perfectly. But not with generics...

1条回答
叛逆
2楼-- · 2019-02-17 01:22

When you request

@Inject MyDao<Customer> dao;

the container knows that you want a bean specifically of type MyDao<Customer>. If such a bean exists and its type information is known, then the container can satisfy the injection. For example, the type information is preserved in your @Produces annotated method

@Produces
MyDao<Product> getDaoProduct() {

The container uses reflection to retrieve that parameterized type and can match it to the requested @Inject field.

With

abstract class MyView<T> {
    @Inject
    MyDao<T> dao;

however, all the container knows is that you want a MyDao. T is a type variable, not a concrete parameterization. The container cannot assume a specific type for it. In your case, both of the @Produces beans would match and there would be ambiguity.


In your example, we know from the context that it really wants a MyDao<Customer>. That doesn't seem to be something your container is capable of doing, ie. trying to resolve the type parameter to a concrete type argument for a parameterized subclass.

查看更多
登录 后发表回答