Дженерики и связь типов

Рейтинг: 2Ответов: 1Опубликовано: 08.04.2011

Добрый день.

У меня, как у человека, привыкшего к C++ и шаблонам, постоянно возникают какие-то недопонимания с дженериками.

Итак, предположим, у нас есть принтеры, которые умеют печатать некоторые объекты:

public interface Printer<X> { 
    public void print(X obj); 
}

Есть список, на каком принтере и что надо напечатать:

class PrintInfo<X> { 
    public Printer<X> printer; 
    public X obj; 
}

Queue<PrintInfo<?>> q;

Ттеперь хочется начать печатать:

PrintInfo<?> pi = q.poll(); 
pi.printer.print(pi.obj); // FAIL

Проблема в том, что Джава почему-то в упор не видит, что это корректный вызов, хотя связь типов, вроде бы, очевидна. Объясните, пожалуйста, почему так происходит, и какие есть варианты обхода?


P.S. Я обошёл, добавив в PrintInfo метод print, который, собственно, печатает свой объект на своём принтере, и вызываю его.

Ответы

▲ 4Принят

Конечно не видит. Это из-за "?". Вы пытаетесь взять неизвестность и напечатать её с помощью неизвестного принтера. Но две разные неизвестности не всегда совместимы.

Возможно, это ошибка дизайна. Лично мне кажется, что генерики здесь ни к чему.

UPD

ОК. Возможно я немного погорячился :)

Вообще, если не хочется переделывать, то вы можете спрятать печать внутрь джобы

public class PrintTask<T extends Printable> {
    private final PrintStrategy<T> strategy;
    private final T object;

    public PrintTask(PrintStrategy<T> strategy, T object) {
        this.strategy = strategy;
        this.object = object;
    }

    public final void print() {
        strategy.print(object);
    }

}

И тогда можно будет просто делать

do {
    queue.take().print();
} while (....);