это проблема, которую вам, возможно, придется решить в будущем.

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

class A {
  ...
}

class B {
  ...
}

class C extends B {
  ...
}

class D<T extends B> extends A {
  ...
}

class StringMap<T extends A> {
   HashMap<String, T> _elements;
   ...
}

Так что теперь я собираюсь написать класс, который содержит определенныйStringMap тип.

class X {
  StringMap<D<C>> _thing = new StringMap<D<C>>;
  ... 
}

Пока все это работает нормально.D<C> на самом деле это очень длинное имя, и определенная комбинация будет появляться очень часто в других частях кода, поэтому я решил создать класс для конкретной комбинации, чтобы он был более понятным и имел более короткое имя.

class DC extends D<C> {

}

//and go to update X
class X {
  StringMap<D<C>> _thing = new StringMap<D<C>>(); //still works fine
  StringMap<DC> _thing = new StringMap<DC>(); //error
  ... 
}

Затмение дает ошибку

Связанное несоответствие: типDC не является допустимой заменой ограниченного параметра<T extends A> типаStringMap<T>

Итак, вопрос в том, почему это не просто работает?DC ничего не делает, но расширяетD<C> и повторить конструкторы. ПочемуStringMap видетьDC как отличается, когда это просто дочерний класс чего-то, что он исключает?

РЕДАКТИРОВАТЬ:
Хорошо, переработал пример, чтобы быть ближе к тому, что я на самом деле делаю. Я проверил это, и он выдает ошибку. Здесь я использую универсальный тип, чтобыclone() возвращает правильный класс для тех, кто реализует его в дереве наследования. Тогда в подклассах я используюB<T extends B<T>> чтобы гарантировать, что подклассыB переходят в подкласс B как универсальный типT.

public abstract class Undoable<T> implements Comparable<T> {
  public abstract T clone();
  public abstract void updateFields(T modified);
}

abstract public class A<T extends A<T, U>, U extends Comparable<U>>
    extends Undoable<T> {
  abstract U getKey();

  @Override
  public int compareTo(T element)
  {
    return getKey().compareTo(element.getKey());
  }
}

public class B<T extends B<T>> extends A<T, String> {
  @Override
  public T clone()
  {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void updateFields(T modified)
  {
    // TODO Auto-generated method stub
  }

  @Override
  String getKey()
  {
    // TODO Auto-generated method stub
    return null;
  }
}

public class C extends B<C> {

}

public class D<T extends B<T>> extends A<D<T>, String> {
  @Override
  String getKey()
  {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public D<T> clone()
  {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void updateFields(D<T> modified)
  {
    // TODO Auto-generated method stub
  }
}

public class DC extends D<C> {

}

public class StringMap<T extends Undoable<T>> {
  HashMap<String, T> _elements;

}

public class Main {
  public static void main(String[] args)
  {
    StringMap<D<C>> _thing = new StringMap<D<C>>(); //works
    StringMap<DC> _thing1 = new StringMap<DC>(); //error
//Bound mismatch: The type DC is not a valid substitute for
//the bounded parameter <T extends Undoable<T>> of the type StringMap<T>

  }
}

Ответы на вопрос(4)

Ваш ответ на вопрос