[java] Instantiating a generic type

I'm trying to convert an existing class to use generics, and am getting stumped while converting the constructors.

The original class was a POJO that contained logic for moving from one room to another in a text-based console game. Literally, it was a class that held some string triggers that would fire the action (eg. the user types "walk right"), a description, and a pointer to the new Location.

The current, non generic version of the class looks like this:

public class Navigation implements Serializable {     private static final long serialVersionUID = 1L;     private String trigger;     private String description;     private Location target;      public Navigation() {         this("", "", new Location());     }      public Navigation(String trigger, String description, Location target) {         this.trigger = trigger;         this.description = description;         this.target = target;     }      // plus getters, setters, etc. } 

(The Location class is another POJO that describes a location. It is irrelevant.)

I want to extend the Navigation class to be able to handle targets that are not Locations. I thought that the best way to do this would be to convert the Navigation class to use generics, so I tried this:

public class Navigation<T> implements Serializable {     private static final long serialVersionUID = 2L;     private String trigger;     private String description;     private T target;      public Navigation() {         this("", "", new T());     }      public Navigation(String trigger, String description, T target) {         this.trigger = trigger;         this.description = description;         this.target = target;     }      // plus getters, setters, etc. } 

However, this doesn't compile at the line this("", "", new T()); because T cannot be instantiated. Is is possible to instantiate the generic type object in this context?

This question is related to java generics

The answer is


You basically have two choices:

1.Require an instance:

public Navigation(T t) {     this("", "", t); } 

2.Require a class instance:

public Navigation(Class<T> c) {     this("", "", c.newInstance()); } 

You could use a factory pattern, but ultimately you'll face this same issue, but just push it elsewhere in the code.


You cannot do new T() due to type erasure. The default constructor can only be

public Navigation() {     this("", "", null); } 

‚Äč You can create other constructors to provide default values for trigger and description. You need an concrete object of T.


No, and the fact that you want to seems like a bad idea. Do you really need a default constructor like this?