Google Maps, метод Add Markers in Callback работает только один раз (Android)

Поскольку никто не дал удовлетворительного ответа, правильный ответ кажется «из-за недостатка языка Java».

polygenelubricants предоставили хороший обзор плохих вещей, происходящих с ковариантностью Java-массива, которая это ужасная особенность сама по себе. Рассмотрим следующий фрагмент кода:

String[] strings = new String[1];
Object[] objects = strings;
objects[0] = 0;

Этот явно неправильный код компилируется, не прибегая к какой-либо «супер» конструкции, поэтому ковариация массива не должна использоваться в качестве аргумента.

Теперь, здесь у меня есть вполне допустимый пример кода, требующего super в параметре named type:

class Nullable<A> {
    private A value;
    // Does not compile!!
    public <B super A> B withDefault(B defaultValue) {
        return value == null ? defaultValue : value;
    }
}

Потенциально поддерживая некоторое приятное использование:

Nullable<Integer> intOrNull = ...;
Integer i = intOrNull.withDefault(8);
Number n = intOrNull.withDefault(3.5);
Object o = intOrNull.withDefault("What's so bad about a String here?");

Последний фрагмент кода не компилируется, если я вообще удаляю B, поэтому B действительно необходим.

Обратите внимание, что функция, которую я пытаюсь реализовать, легко получить, если я инвертирую порядок объявлений параметров типа, изменив ограничение super на extends. Однако это возможно только в том случае, если я переписываю метод как статический:

// This one actually works and I use it.
public static <B, A extends B> B withDefault(Nullable<A> nullable, B defaultValue) { ... }

Дело в том, что это ограничение языка Java действительно ограничивает некоторые возможные полезные функции и может потребовать уродливые обходные пути. Интересно, что произойдет, если нам понадобится withDefault, чтобы быть виртуальным.

Теперь, чтобы соотнести с тем, что говорят полигеномассы, мы используем B здесь, чтобы не ограничивать тип объекта, переданного как defaultValue ( см. строку, используемую в примере), а скорее ограничить ожидания вызывающего абонента возвратом объекта. В качестве простого правила вы используете extends с типами, которые вы требуете, и super с типами, которые вы предоставляете.

0
задан Pablo Reyes 24 February 2015 в 19:52
поделиться