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, eg
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 ?
The easiest way would be to pass the responsibility on to whoever actually instanciates and uses instances of BaseSelectorComposer
, ie:
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> {
...
}
ie, 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).
In general, this is a hard-to-workaround scenario. Coming from .NET background, I have personally found very few cases where I could work this out, since Java does not support static generic type resolution (like for instance in .NET where you can use typeof(T)
).
To work this around I recommend that you find a way to either get the class externally, or an instance of that class. A possible solution would be to change the doAfterCompose
method in one of the following ways:
@Override
public void doAfterCompose(Window comp, Class<?> entityClass) throws Exception {
super.doAfterCompose(comp);
this.searchObject =
new HibernateSearchObject<T>(entityClass);
...
}
-or-
@Override
public void doAfterCompose(Window comp, SomeEntity entity) throws Exception {
super.doAfterCompose(comp);
this.searchObject =
new HibernateSearchObject<T>(entity.getClass());
...
}
If you cannot modify the method signature (I see it is an override), try to use a member of the class BaseSelectorComposer<T>
that will hold the desired Class<?>
instance.
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);
...
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.