Reputation: 4991
I have a simple interface like this.
public interface EntityClass
{
public void setId(final Integer id);
public Integer getId();
}
and a class
public Student implements EntityClass
I am trying to code a class which uses a generic type T
but still is a instanceof EntityClass
a EntityClass subclass
something like this.
public abstract class CustomizableQueriesForClazzAndFields<T extends EntityClass>
That's is the project inside that class i want a method like this.
public List<T>getMultipleClazzWithFields(final String ...fields){return of(genericType).retrieve(fields);}
private MyCriteria of(final Class<? extends EntityClass>applyToClazz){........}
MyCriteria is a wrapper over org.hibernate.Criteria.
And in my implementation would do something like this.
public final class TestCustom extends CustomizableQueriesForClazzAndFields<Student>
{
public static void main(String[] args)
{
final TestCustom clazz = new TestCustom();
final List<Student>a=clazz.getMultipleClazzWithFields("id","name","phone");
a.stream().forEach(clazz::consumer);
}
}
Doing this code i would like to be represent it like this using generics.
public List<Student>getMultipleClazzWithFields(final String ...fields){return of(Student.class).retrieve(fields);}
But i dont know how to represent this or if it's possible.
public List<T>getMultipleClazzWithFields(final String ...fields){return of(genericType).retrieve(fields);}
Which genericType should be represent it as Student
the same Student
as
public final class TestCustom extends CustomizableQueriesForClazzAndFields<Student>
Or represent it as
public final class TestCustom extends CustomizableQueriesForClazzAndFields<School>
And would do something like
public List<School>getMultipleClazzWithFields(final String ...fields){return of(School.class).retrieve(fields);}
Because i was diving like this
public List<T>getMultipleClazzWithFields(final String ...fields){return of(T).retrieve(fields);}
But the compiler kicks me and says.
cannot find symbol
symbol: variable T
location: class CustomizableQueriesForClazzAndFields<T>
where T is a type-variable:
T extends EntityClass declared in class CustomizableQueriesForClazzAndFields
----
(Alt-Enter shows hints)
I also try
public abstract class CustomizableQueriesForClazzAndFields<Class<T extends EntityClass>>
But says.
> expected
----
(Alt-Enter shows hints)
Or how i can accomplish my desire code.. any workaorund.
Because i a kind annoying passing as parameter.
UPDATE
All i wanna to do is pass a SubClass of EntityClass
and creates.
session.createCriteria(genericType);
As well gives me the List but i dont know if it's possible to catch or capture the generic type pass CustomizableQueriesForClazzAndFields<Student>
and passed to of()
method which is who created the org.hibernate.Criteria object
i cannot pass only a T
value because in my graph would like to be a subclass of EntityClass
a not just a raw T value.
I need to catch or capture
CustomizableQueriesForClazzAndFields<Student>
Student generic type.
If this possible or i am dreaming sorry by my poor english.
Thank a lot and best regards from Venezuela..
Upvotes: 0
Views: 1309
Reputation: 88707
Approach 1:
I'm not sure I fully understand your question but I have the feeling you want something like this:
public abstract class CustomizableQueriesForClazzAndFields<T extends EntityClass> {
public List<T> getMultipleClazzWithFields(final Class<T> clazz, final String ...fields){
return of(clazz).retrieve(fields);
}
private MyCriteria of(final Class<T> applyToClazz) {
...
}
}
The compiler can't create/retrieve an instance of T
at runtime just from inferred data, hence you have to pass that information somehow e.g. as a parameter:
List<Student> l = getMultipleClazzWithFields(Student.class, "field1", "field2");
Approach 2:
Instead of passing Class<T>
as a parameter you could also create subclasses for every T
, e.g. class StudentQueries extends CustomizableQueriesForClazzAndFields<Student>
, and then use reflection to find out the type of T
. Please note though, that this would only work for sublcasses that define the concrete type of T
.
Which approach is better depends on your needs but if it's just for that query I'd pass the class of the entity as a call parameter and skip all those subclasses that would be needed otherwise.
Update: if you want to implement the second approach (subclasses) have a look here for some code on how to use reflection to look up the type of T
: http://www.artima.com/weblogs/viewpost.jsp?thread=208860
Upvotes: 1