Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics - Class<?> constructor argument issue

I've used Java for quite some time now, but some things are still not very clear to me, especially when it comes to generics...

Here's the thing: I have this Search class that I'm using (see here for details), that is constructed like this:

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

Further more, I have a parametrized generic wrapper around this, as follows:

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

Now, what I need is the following: I'd like to create parametrized class, that contains this class as its field, e.g.

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...??? );
        ...
    }
    ...
}

I think that the problem I'm facing is obvious from the given example.
Can someone advise what can be done here, or some alternative ?

like image 828
Less Avatar asked Jun 06 '13 13:06

Less


People also ask

Can a generic class have constructor?

Can we have a generic constructor? No, generic constructors are not allowed.

How do you pass a constructor as an argument in Java?

Constructors can be passed as arugments to methods using a method reference, somewhat like a function pointer in C++. This can be a Function type with one argument or a BiFunction type with two arguments, either way its a lambda returning a class of the type it constructs.

Which constructor Cannot take arguments?

A constructor that takes no parameters is called a parameterless constructor. Parameterless constructors are invoked whenever an object is instantiated by using the new operator and no arguments are provided to new .

How do you pass a generic argument in Java?

When we declare an instance of a generic type, the type argument passed to the type parameter must be a reference type. We cannot use primitive data types like int, char.


1 Answers

The easiest way would be to pass the responsibility on to whoever actually instanciates and uses instances of BaseSelectorComposer, i.e.:

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);
        ...
    }
    ...
}

If your BaseSelectorComposer is an abstract subclass, which is only ever used like

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

i.e., as base class for classes, which "bind" the type parameters, there are ways to obtain the type information via reflection (though this is incredibly ugly, since this is not really well-supported in the API IMHO).

like image 64
Dirk Avatar answered Sep 30 '22 05:09

Dirk