How can I instantiate a generic type in Java?

Due to type erasure in Java, you can't instantiate generic objects. Normally you could keep a reference to the Class object and use Class.newInstance() However, this only works for the default constructor. Since you want to use a constructor with parameters, you'll need to look up the Constructor object and use it for the instantiation, using reflection: protected T getProperty(String key, T fallback, Class clazz) { String value = properties.

GetProperty(key); if (value == null) { return fallback; } else { //try getting Constructor Constructor constructor; try { constructor = clazz. GetConstructor(new Class { String. Class }); } catch (NoSuchMethodException nsme) { //handle constructor not being found } //try instantiating and returning try { return constructor.

NewInstance(value); } catch (InstantiationException ie) { //handle InstantiationException } catch (IllegalAccessException iae) { //handle IllegalAccessException } catch (InvocationTargetException ite) { //handle InvocationTargetException } } } However, seeing how much trouble it is to achieve this, including the performance cost of using reflection, it's worth looking into other approaches first If you absolutely need to take this route, and if T is limited to a distinct set of types known at compile time, a compromise would be to keep a static Map of Constructors which is loaded at startup, so you don't have to dynamically look them up at every call to this method. For example a MapWhich is populated using a static block.

Due to type erasure in Java, you can't instantiate generic objects. Normally you could keep a reference to the Class object and use Class.newInstance(). However, this only works for the default constructor.

Since you want to use a constructor with parameters, you'll need to look up the Constructor object and use it for the instantiation, using reflection: protected T getProperty(String key, T fallback, Class clazz) { String value = properties. GetProperty(key); if (value == null) { return fallback; } else { //try getting Constructor Constructor constructor; try { constructor = clazz. GetConstructor(new Class { String.

Class }); } catch (NoSuchMethodException nsme) { //handle constructor not being found } //try instantiating and returning try { return constructor. NewInstance(value); } catch (InstantiationException ie) { //handle InstantiationException } catch (IllegalAccessException iae) { //handle IllegalAccessException } catch (InvocationTargetException ite) { //handle InvocationTargetException } } } However, seeing how much trouble it is to achieve this, including the performance cost of using reflection, it's worth looking into other approaches first. If you absolutely need to take this route, and if T is limited to a distinct set of types known at compile time, a compromise would be to keep a static Map of Constructors which is loaded at startup, so you don't have to dynamically look them up at every call to this method.

For example a Map or Map, which is populated using a static block.

1 Even with a default constructor, it is better to use a Constructor object than to use Class.newInstance(). The error handling is different; using the Class method, some exceptions are reported with a misleading type. The Constructor method is consistent with other dynamic invocations.

– erickson Aug 2 at 18:16 @Kublai Khan — Works! Even better, I was able to get klazz as Class klazz = (Class)fallback.getClass(); to eliminate the extra parameter. Thanks so much for your help!

Edit: I was starting to wonder about caching as soon as reflection entered the picture; I'll look at static blocks for that. – Ben Blank Aug 2 at 18:24 Glad I could help. Just keep in mind that all dynamic lookups using reflection are quite expensive as they cannot be optimized at compile time.

– Kublai Khan Aug 2 at 18:28 @erickson - thanks I wasn't aware of this. – Kublai Khan Aug 2 at 18:29 @Kublai Khan — At this point, I'm thinking I may use this generic version during development, but switch to explicitly-typed methods before release. By examining the cache, I'll be able to tell what types I've ended up needing to support.

– Ben Blank Aug 2 at 18:34.

This is something that you cannot do. Because of type erasure, the type T, while known at compile time, is not available to the JVM at run time. For your specific problem, I think the most reasonable solution is to manually write the code for each different type: protected String getProperty(String key, String fallback) { ... return new String(value); } protected Double getProperty(String key, Double fallback) { ... return new Double(value); } protected Boolean getProperty(String key, Boolean fallback) { ... return new Boolean(value); } protected Integer getProperty(String key, Integer fallback) { ... return new Integer(value); } Notes: In the Java standard API, you will find many places where there is a set of related methods that only differ by the input types.In C++, your probably could probably be solved by templates.

But C++ introduces many other problems...

Generics are implemented using type erasure in Java. In English terms, most generic information are lost at compile time, and you can't know the actual value of T at runtime. This means you simply can't instanciate generic types.An alternate solution is to provide your class with the type at runtime: class Test { Class klass; Test(Class klass) { this.

Klass = klass; } public void test() { klass.newInstance(); // With proper error handling } } Edit: New example closer to your case static T getProperty(String key, T fallback, Class klass) { // ... if (value == null) { return fallback; } return (T) klass.newInstance(); // With proper error handling }.

I need to have a single instance of my class (PropertiesExample, here) be able to read properties of various types from the same file. I'll add a usage example to my question. :-) – Ben Blank Aug 2 at 18:01 First bit of code doesn't compile.

T on the constructor is masking generic argument, and is in the wrong position. Additionally, exception checking is needed for newInstance(). – Chris Dennett Aug 2 at 18:05 Typo, fixed now.

Exception checking was ommited for readability, hence the "With proper error handling" comment. – Vivien Barousse Aug 2 at 18:10.

If you want to keep your existing method signature do it this way. Import java.lang.reflect. InvocationTargetException; import java.util.

Properties; public class Main { private final Properties properties; public Main() { this. Properties = new Properties(); this.properties. SetProperty("int", "1"); this.properties.

SetProperty("double", "1.1"); } public T getProperty(final String key, final T fallback) { final String value = this.properties. GetProperty(key); if (value == null) { return fallback; } else { try { return (T) fallback.getClass(). GetConstructor(new Class { String.

Class } ). NewInstance(value); } catch (final InstantiationException e) { throw new RuntimeException(e); } catch (final IllegalAccessException e) { throw new RuntimeException(e); } catch (final InvocationTargetException e) { throw new RuntimeException(e); } catch (final NoSuchMethodException e) { throw new RuntimeException(e); } } } public static void main(final String args) { final Main m = new Main(); final Integer I = m. GetProperty("int", new Integer("0")); final Double d = m.

GetProperty("double", new Double("0")); System.out. Println(i); System.out. Println(d); } }.

Try this: protected T getProperty(String key, T fallback) { String value = properties. GetProperty(key); if (value == null) { return fallback; } else { Class FallbackType = fallback.getClass(); return (T)FallbackType. Cast(value); } }.

See edited post. – maclema Aug 2 at 18:03 This is better, but you need to create a new instance via reflection, using the value as an argument. The downvote is not from me, by the way; I was going to suggest this approach myself, but I wasn't able to figure out a way to do it type safely.

Try to get rid of the unsafe cast to T. – erickson Aug 2 at 18:18.

Using the technique described here I get an error because class tokens cannot be generic. Take the example below. I want to instantiate some subclass of Creator that implements Creator.

The actual class name is passed in as a command line argument. The idea is to be able to specify an implementation of Creator at runtime.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions