Дженерики Java + статические фабричные методы = [паника]

Я думал, что уже разберусь с дженериками Java. Но теперь я снова беспомощен.

У меня есть общий класс, в котором c-tor создает экземпляр с правильным типом, а статический фабричный метод создает несоответствие типов.

Посмотрите на следующий код:

public class _GenericFactoryMethods {

  public final static class DemoClass<T1, T2> {
    private final T1 _1;
    private final T2 _2;

    // static factory method
    public static <T1, T2> DemoClass<T1, T2> create(T1 _1, T2 _2) {
      return new DemoClass<T1, T2>(_1, _2);
    }

    // usual c-tor
    public DemoClass(T1 _1, T2 _2) {
      this._1 = _1;
      this._2 = _2;
    }

    public T1 get1() { return _1; }

    public T2 get2() { return _2; }
  }

  public void doSomething() {
    String str = "test";

    Class<? extends CharSequence> _1 = str.getClass();
    CharSequence _2 = str;

    // works
    DemoClass<Class<? extends CharSequence>, CharSequence> dc1 =
        new DemoClass<Class<? extends CharSequence>, CharSequence>(_1, _2);

    // compile error
    DemoClass<Class<? extends CharSequence>, CharSequence> dc2 =
        DemoClass.create(_1, _2);
  }

}

Ошибка:

Uncompilable source code - incompatible types
required: _GenericFactoryMethods.DemoClass<java.lang.Class<? extends java.lang.CharSequence>,java.lang.CharSequence>
found:    _GenericFactoryMethods.DemoClass<java.lang.Class<capture#794 of ? extends java.lang.CharSequence>,java.lang.CharSequence>

Пожалуйста, помогите понять и решить эту проблему.
(Мне действительно нужны статические фабричные методы для некоторых из таких классов).

EDIT
Может ли кто-нибудь также объяснить, почему должны использоваться явные параметры типа?


person java.is.for.desktop    schedule 22.02.2010    source источник


Ответы (2)


Пытаться

DemoClass.<Type1, Type2>create(_1, _2);

Насколько я помню из презентации Джоша Блоха его Effective Java 2nd Edition: «Бог убивает котенка каждый раз, когда вы указываете явный параметр типа». Старайтесь избегать подобных конструкций.

person Roman    schedule 22.02.2010
comment
Спасибо. Ну, писать обычный конструктор еще дольше ;) А для моего частного случая (не примера) мне очень нужны статические фабричные методы. - person java.is.for.desktop; 22.02.2010
comment
Эх, нет никаких шансов превзойти ответы с упоминанием котят. Вступительная часть! ;) - person sfussenegger; 22.02.2010
comment
@sfussenegger: ага, это как измена, все любят котят ))) - person Roman; 22.02.2010

В этом случае вы должны явно установить универсальный тип:

dc2 = DemoClass.<Class<? extends CharSequence>, CharSequence>create(_1, _2);
person sfussenegger    schedule 22.02.2010