I am designing a simple Data Access Object for my Java application. I have a few classes (records) that represents a single row in tables like User
and Fruit
.
I would like to have a single method for getting all records of a specific type.
For the moment I have it like this:
public List<User> getAllUsers() {
...
}
public List<Fruit> getAllFruits() {
...
}
....
But I would like to have a single polymorphic method like this (wrong):
public List<T> getAllRecords(Class<T> type) {
if(type instanceof User) {
// Use JDBC and SQL SELECT * FROM user
} else if(type instanceof Fruit) {
// Use JDBC and SQL SELECT * FROM fruit
}
return collection;
}
Example for uses:
List<Fruit> fruits = myDataAccessObject.getAllRecrods(Fruit.class);
List<User> users = myDataAccessObject.getAllRecords(User.class);
How can I do this in Java?
Well, I really don't know if you need it this way. But here is a polymorphic approach. It might help somewhere somehow.
Create different objects for different tables all implementing a common interface. This means you represent each table as an object.
It looks like you want to adapt what Josh Bloch calls a Typesafe Heterogenous Container pattern: you are passing a type token
Class<T>
, and you want back aList<T>
.Plain old THC can map a
Class<T>
to aT
in a typesafe manner, but since you actually want aList<T>
instead, then you want to use what Neal Gafter calls the super type tokens.The following snippet is adapted from Crazy Bob Lee's code posted in Neal Gafter's blog:
Now you can create a super type token like these:
Essentially you pass a
TypeReference<T>
instead of aClass<T>
. The difference is that there is noList<String>.class
, but you can make aTypeReference<List<String>>
.So now we can make our container as follows (the following is adapted from Josh Bloch's original code):
Now we can put the two together:
Neal Gafter argued in his blog that with some more bells and whistles,
TypeReference
for super type tokens will make a worthy inclusion in the JDK.Attachments
References
I believe what you are trying to do is possible with a bit of generics magic. I had to solve the same problem just now and this is what I did:
And unit tests:
Since you say that you don't want you data access methods in different classes(in the comment to anish's answer),I thought why not try something like this.
EDIT:
I would like to add one more of my implementation.
EDIT:
I think this implementation is just as you have asked
I've actually done this in a generic data access library. See Norm. Full source code on Github.
You are pretty close.
This is called a Generic Method.
You will want to specify a parameter like
List<T>
. Then, based upon the type of the list you pass in, Java will infer the generic type to return.Edit:
Poly's answer is very good. It should be easy enough for you to do the following and not have to create a
TypeReference
class.