Tip: How to instantiate a generic Java object with arguments

While writing a text-based database, I fell into the following problem: How do I convert a column of String’s into any wrapper type of my choice? The solution I found is a generic instantiation with a single String argument in its constructor. 

 My demo dataset has the following format:

t 3 b ? ?
z 1 h n c
k 6 a 0 ?

What I want is to read in the dataset (not covered here), and then extract the second column as a list of Integers.

 
public <T> List<T> getColumnAsType(int col, Class<? extends T> t)
throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException,
InvocationTargetException, NoSuchMethodException {

 List<T> list = new ArrayList<T>();
 for (int i = 0; i < size(); i++) {
  T type = t.getConstructor(String.class).newInstance(getValueByIndex(col, i));
  list.add(type);
 }

 return list;
}  

I can use this method like this:  

try {
 List<Integer> list = db.getColumnAsType(1, Integer.class);
 System.out.println(list);
} catch (Exception e) {
 e.printStackTrace();
}

Giving me the following output:

[3, 1, 6]

To understand what really happens here, we need to look at the method definition in more detail. The first line starts with a generic type definition parameter T using the <T> notation. Next is the return type, defined as a generic List of T objects. The last parameter of the method defines the actual type of the T parameter, which in the following code is a Class object:

public <T> List<T> getColumnAsType(int col, Class<? extends T> t)

Finally, we look at how the instantiation happens. For every object in my list, I instantiate a T object with a constructor taking a single String argument. There are of course several pitfals in this code. First of all, you must make sure the generic object really has a single argument constructor matching the value type specified in the “.newInstance” method call. Second, the generic type cant be an abstract class. The “.newInstance” method throws several exceptions which you can read about here.

T type = t.getConstructor(String.class).newInstance(getValueByIndex(col, i));
This entry was posted in Java. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>