Как исправить «аргумент типа S не в границах переменной типа E» в Java - PullRequest
0 голосов
/ 13 февраля 2019

Я пытаюсь сделать полиморфный доступ к различным классам Enum путем определения некоторого базового метода доступа с использованием интерфейсов.Например:

package com.company;

public interface StatesInterface<E extends Enum<E>> {

    E getOneState();
    E getTwoState();
    E getThreeState();
}

И некоторые реализации:

package com.company;

public enum States implements StatesInterface<States> {

    ONE, TWO, THREE, FOUR;

    @Override
    public States getOneState() {
        return ONE;
    }
    @Override
    public States getTwoState() {
        return TWO;
    }
    @Override
    public States getThreeState() {
        return THREE;
    }
}

Примечание: я знаю, что этот код имеет проблемы, потому что интерфейс предоставляет статические значения перечисления через нестатический интерфейс, но я неЯ понятия не имею, как ее решить.

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

package com.company;

public class Lifecycle<S extends StatesInterface> {

    private S state;

    public void transit() {
        state = state.getOneState(); // <---- incompatible types
    }
}

В этом случае я не могу присвоить state.getOneState(); типа Enum типу state типа StatesInterface<Enum>.

Когда я пытаюсь изменить общийвведите Lifecycle<S extends StatesInterface<S>> compiles говорит мне Error:(3, 50) java: type argument S is not within bounds of type-variable E.

Моя цель - создать набор различных классов Enum с общим интерфейсом для создания новых классов, обобщающих класс Lifecycle для определенного типа Enum.

Можно ли добиться этого с помощью предоставленного кода и как это исправить?

1 Ответ

0 голосов
/ 13 февраля 2019

Я думаю, что вы ищете это:

class Lifecycle<S extends Enum<S> & StatesInterface<S>>

По сравнению с вашими определениями, как это:

interface StatesInterface<E extends Enum<E>>

enum States implements StatesInterface<States>

class Lifecycle<S extends StatesInterface>

тогда getOneState() просто возвращаетвведите Object extends Enum<Object>, потому что вы использовали необработанный тип для StatesInterface, не задав ему параметры типа, что несовместимо с типом S extends StatesInterface, что дает вам "Type mismatch: cannot convert from Enum to S"

Изменяя ваше определение на class Lifecycle<S extends Enum<S> & StatesInterface<S>>, вы разрешаете getOneState() возвращать S extends Enum<S> & StatesInterface<S>, что, конечно, совместимо для установки в переменную типа S, S state = getOneState()


Что отнять у этого

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...