Могу ли я заставить конструктор установить более строгую границу для его универсального типа? - PullRequest
1 голос
/ 20 марта 2019

В Java универсальные классы имеют конструкторы для создания экземпляров некоторого универсального типа.Это просто, и вызыватели конструктора могут указать любой тип, который находится в пределах границ.

Возможно ли иметь конструктор, который устанавливает более строгие границы для этого универсального типа?
Например, иметь конструктор, который заставляетуниверсальный тип: String.

public class GenericClass<T extends Serializable> {
    public GenericClass() {
        // normal constructor
    }

    public GenericClass(String argument) {
        // Can I force this constructor to construct a `GenericClass<String>`?
    }
}

// The first constructor can have any type
GenericClass<String> stringInstance = new GenericClass<>();
GenericClass<Integer> intInstance = new GenericClass<>();

// The second constructor is limited to `GenericClass<String>`
stringInstance = new GenericClass<>("with generic type String is okay");
intInstance = new GenericClass<>("with other generic type is not okay");

Я хотел бы, чтобы последняя строка не выполнялась из-за несовместимых типов.

Возможно ли это?

Ответы [ 2 ]

3 голосов
/ 20 марта 2019
public GenericClass(String argument)

Проблема в том, как компилятор должен знать, что String равно T?Нет никакой связи между параметром и параметром универсального типа, и нет способа указать его.Вы можете использовать

public GenericClass(T argument)

и создать его с

new GenericClass<>("foo");

, но это позволит создать экземпляр GenericClass с объектом любого типа.

Вы можетеПримерно достигните того, что вы хотите, используя наследование, хотя вам нужно ввести второй класс:

class GenericClass<T extends Serializable> {
    public GenericClass() {

    }
}

class StringClass extends GenericClass<String> {
    public StringClass(String argument) {

    }
}

Вы можете ввести интерфейс, и оба класса реализуют его, если вы хотите избежать использования наследования.Вот что я сделаю.

2 голосов
/ 20 марта 2019

Один из способов вызвать сбой в последней строке:заводской метод ofString:

public static GenericClass<String> ofString(String s) {
    GenericClass<String> gc = new GenericClass<>();
    // do stuff to gc
    return gc;
}
...