Reputation: 289
I would like to implement a generic method which does something akin to the following:
private <T> void addToSize(ArrayList<T> list, Class<T> type, int size) {
int currentSize = list.size();
for(int i = currentSize; i < size; i++) {
try {
list.add(type.newInstance());
} catch (InstantiationException e) {
logger.error("", e);
} catch (IllegalAccessException e) {
logger.error("", e);
}
}
}
The method above works for something like so:
ArrayList<Integer> test = new ArrayList<Integer>();
addToSize(test, Integer.class, 10);
but I also want it to work for...
ArrayList<ArrayList<Integer>> test = new ArrayList<ArrayList<Integer>>();
addToSize(test, ArrayList.class, 10); //Is this possible?
Is this possible?
Upvotes: 4
Views: 187
Reputation: 122519
You could do this
ArrayList<ArrayList<Integer>> test = new ArrayList<ArrayList<Integer>>();
addToSize(test, (Class<ArrayList<Integer>>)(Class<?>)ArrayList.class, 10);
Class literals are always Class
parameterized with the raw type. Getting it into a Class
parameterized with something generic is somewhat tricky.
Upvotes: 0
Reputation: 425348
You could use the factory pattern:
public interface Factory<T> {
public T create();
}
private static <T> void addToSize( ArrayList<T> list, Factory<T> factory, int size ) {
int currentSize = list.size();
for ( int i = currentSize; i < size; i++ ) {
list.add( factory.create() );
}
}
Then for your example (implemented anonymously):
ArrayList<ArrayList<Integer>> test2 = new ArrayList<ArrayList<Integer>>();
addToSize( test2,
new Factory<ArrayList<Integer>>() {
public ArrayList<Integer> create() {
return new ArrayList<Integer>( );
}
}, 10 ); // compiles
The cool thing about this is the class doesn't need a default constructor, and you could pass values into its constructor and/or use the builder pattern. The complexity of the create()
method implementation is arbitrary.
Upvotes: 6