Вернуть нужно точно такую ​​же последовательность дженериков - PullRequest
0 голосов
/ 25 августа 2018

Я пытаюсь выполнить это:

public class Value<T extends Number> {}
public class Currency<V extends Value> {}
public class ValuePair<V extends Value, C extends Currency<V>> {}
public class UnitStack<E extends Enum, V extends Value> {}
public class UnitCurrency<V extends Value, U extends Enum, S extends UnitStack<U, V>> extends Currency<V> {}
public class CustomStack extends UnitStack<CustomStack.CustomEnum, Value<Double>> {
  public enum CustomEnum {
    ;
  }
}

public class Program {
  public static void main(String[] args){
    test();
  }
  public static ValuePair<Value<Double>, UnitCurrency<Value<Double>, Enum, UnitStack<Enum, Value<Double>>>> test() {
    return new ValuePair<Value<Double>, UnitCurrency<Value<Double>, CustomStack.CustomEnum, CustomStack>>();
  }
}

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

/tmp/java_UHRI1F/Program.java:6: error: incompatible types: ValuePair<Value<Double>,UnitCurrency<Value<Double>,CustomEnum,CustomStack>> cannot be converted to ValuePair<Value<Double>,UnitCurrency<Value<Double>,Enum,UnitStack<Enum,Value<Double>>>>
    return new ValuePair<Value<Double>, UnitCurrency<Value<Double>, CustomStack.CustomEnum, CustomStack>>();
           ^
1 error

Поскольку CustomEnum расширяет Enum, а CustomStack расширяет UnitStack.Но если вы используете Generics в возвращаемой последовательности, вам нужен точно такой же класс, который здесь является проблемой.Есть ли какое-либо решение этой проблемы с генериками?

Вот некоторые объяснения Энди Тернера и всем другим, которые не понимают, почему я так часто использую генерики:

Я понимаю Currency только как самопредставляющий, который может отображать совместимые значения.Я на самом деле получил огромную абстрактную систему, которая прекрасно работает с этим поведением.Program.class на самом деле class, который преобразует значение из одного UnitStack в другое UnitStack.

Я на самом деле хочу создать абстрактный интерфейс для Enums, но, похоже, это такчто Enums нельзя расширить с помощью моих интерфейсов, поэтому я использую inbody Enums.Также в прошлом у меня были другие проблемы с Enums, потому что они кажутся статическими окончательными и не клонируемыми, что делает Enums для меня часто бесполезными.

Value используется так часто, потому что я получил RangeValue Мне нужно иметь одно числовое значение, которое можно использовать для различных математических задач, и я использую его для логических случаев, которые могут быть решены с различными типами чисел, например, если вы покупаете сырые яйца, вы не можете купить яйцо 0,75 илиболее техническим примером в реальном мире будет интеграция различных API для криптовалюты, которые используют разные типы чисел.

Предлагаемые вами изменения не устраняют ошибку и вынуждают меня использовать еще больше обобщений.Извините, но это так.Как я известен как ernest-k обобщенные комментарии являются инвариантными, что создает эту ошибку, даже если я добавляю универсальный номер Number для каждого класса.

Дополнительные пояснения к решению, которое япоиск

Я просто хочу знать, есть ли у них какое-либо решение этой проблемы без повторного использования дженериков.Решение, которое заставит меня использовать дженерики, которые должны быть определены типами init, заставит меня создать экземпляр для каждого преобразования единицы, что было первой идеей, но стоило бы много ресурсов.

Здесь мойинтерфейс для UnitStackTranslation:

public interface UnitStackTranslation<F extends UnitStack, T extends UnitStack, FV extends ValuePair, TV extends ValuePair> {
TV translateFrom(FV value, F from, T to);
FV translateTo(TV value, T to, F from);
}
...