You can't do exactly what you have posted, because in Java generics are not reified. However, you can modify your example using type tokens, although this is rather ugly. For example:
private class StreamOpener<T1, T2>
{
T1 v1;
StreamOpener(String fileName, Class<T1> t1Class, Class<T2> t2Class)
{
try
{
Constructor<T2> t2Constructor = t2Class.getConstructor(String.class);
T2 v2 = t2Constructor.newInstance(fileName);
Constructor<T1> t1Constructor = t1Class.getConstructor(t2Class);
v1 = constructor.newInstance(v2);
}
catch (NoSuchMethodException|SecurityException|InstantiationException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e) // yuck
{
System.err.println("Reflection error, fire your programmer");
System.exit(-1);
}
catch (FileNotFoundException e)
{
System.err.println("File " + fileName + " not found. Exiting");
System.exit(-1);
}
catch (Exception e)
{
System.err.println("Error on file " + fileName + " Exiting");
System.exit(-1);
}
}
}
However, the above is pretty awful code. Instead, you could delegate the creation of T1 to some interface like this:
interface StreamCreator<T> {
T open() throws Exception; // code smell
}
Then, you could invoke this whenever you need an object. One implementation might return new Scanner(new InputStream(fileName))
. Another implementation could return new PrintWriter(new FileOutputStream(fileName))
. And since it's a functional interface, you can define implementations inline with lambdas, in Java 8.
On the other hand, I'm struggling to figure out why you would want to do this in the first place. A Scanner and a PrintWriter expose two totally different interfaces. So how would it be useful to make a single function that could create both of them, in different ways? The calling code would have to be specific to either a Scanner or a PrintWriter, so why not just create the Scanner or PrintWriter using two separate methods?