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 ?
Can we have a generic constructor? No, generic constructors are not allowed.
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.
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 .
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With