Reputation: 15185
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 Location
s. 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?
Upvotes: 3
Views: 106
Reputation: 41087
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
.
Upvotes: 2
Reputation: 424993
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.
Upvotes: 4
Reputation: 12766
No, and the fact that you want to seems like a bad idea. Do you really need a default constructor like this?
Upvotes: 2