简体   繁体   中英

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 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?

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.

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

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM