Как использовать общий с параметром типа и подстановочными знаками вместе? - PullRequest
1 голос
/ 16 июля 2011

Вот код, который не компилируется. Я хотел бы содержать произвольные пары Class<?> (ключ) и Map<Long, ObjectDescriptors<?>> (значения) внутри typeMap;

Из других методов я хочу использовать одну из карт значений с конкретным типом, но алгоритмы должны быть общими. Я написал метод getIdentityMap() для доставки карты с конкретным, но универсальным типом.

Как мне изменить код для компиляции, будучи универсальным?

Заранее спасибо.

    private final Map<Class<?>, Map<Long, ObjectDescriptor<?>>> typeMap = new HashMap<Class<?>, Map<Long,ObjectDescriptor<?>>();

private <T> Map<Long, ObjectDescriptor<T>> getIdentityMap(Class<T> type) {
    Map<Long, ObjectDescriptor<T>> identityMap = typeMap.get(type);
    if (identityMap == null) {
        identityMap = new HashMap<Long, ObjectDescriptor<T>>();
        typeMap.put(type, identityMap);
    }
    return identityMap;
}

РЕДАКТИРОВАТЬ: Вот ошибки компилятора:

  • В строке: Map<Long, ObjectDescriptor<OBJECT_TYPE>> identityMap = typeMap.get(type);
    • ошибка компилятора: Type mismatch: cannot convert from Map<Long,ObjectDescriptor<Object>> to Map<Long,ObjectDescriptor<OBJECT_TYPE>>
  • В строке: typeMap.put(type, identityMap);
    • ошибка компилятора: The method put(Class<?>, Map<Long,ObjectDescriptor<Object>>) in the type Map<Class<?>,Map<Long,ObjectDescriptor<Object>>> is not applicable for the arguments (Class<OBJECT_TYPE>, Map<Long,ObjectDescriptor<OBJECT_TYPE>>)

РЕДАКТИРОВАТЬ: изменил общие типы атрибута карты в?

Ответы [ 2 ]

1 голос
/ 16 июля 2011

Вы можете сделать это, если хотите немного переделать дизайн и все в порядке с одним неконтролируемым приведением (которое никогда не должно подвести IMO).

public class TmpTest {

    public static void main(final String[] args) {
        ClassDescriptorMap m = new ClassDescriptorMap();

        LongDescriptorMap<String> identityMap = m.getIdentityMap(String.class);
        identityMap.put(1L, Arrays.asList("hi"));
        System.out.println(identityMap);
        identityMap = m.getIdentityMap(String.class);
        identityMap.put(2L, Arrays.asList("hello"));
        System.out.println(identityMap);

        LongDescriptorMap<Object> identityMap2 = m.getIdentityMap(Object.class);
        System.out.println(identityMap2);
    }

}

class ClassDescriptorMap {

     private final Map<Class<?>, LongDescriptorMap<?>> typeMap = new HashMap<Class<?>, LongDescriptorMap<?>>();

     public <T> LongDescriptorMap<T> getIdentityMap(Class<T> type) {
         @SuppressWarnings("unchecked")
        LongDescriptorMap<T> identityMap = LongDescriptorMap.class.cast(typeMap.get(type));
         if (identityMap == null) {
             identityMap = new LongDescriptorMap<T>();
             typeMap.put(type, identityMap);
         }
         return identityMap;
     }

     @Override
     public String toString() {
         return typeMap.toString();
     }
}

class LongDescriptorMap<T> {

    private Map<Long, List<T>> map = new HashMap<Long, List<T>>();

    public List<T> get(Object key) {
        return map.get(key);
    }

    public List<T> put(Long key, List<T> value) {
        return map.put(key, value);
    }

    @Override
    public String toString() {
        return map.toString();
    }

}
1 голос
/ 16 июля 2011

Вы не можете создать универсальный экземпляр с "T".Попробуйте использовать «?»

 private final Map<Class<?>, Map<Long, ObjectDescriptor<?>>> typeMap = new HashMap<Class<?>, Map<Long,ObjectDescriptor<?>>>();


private <T> Map<Long, ObjectDescriptor<?>> getIdentityMap(Class<?> type) {
    Map<Long, ObjectDescriptor<?>> identityMap = typeMap.get(type);
    if (identityMap == null) {
        identityMap = new HashMap<Long, ObjectDescriptor<?>>();
        typeMap.put(type, identityMap);
    }
    return identityMap;
}

. Как уже упоминалось в комментариях, это происходит из-за стирания Java для обеспечения совместимости со старыми классами, которые не использовали универсальные шаблоны.Компилятор удаляет информацию о типе из параметров и аргументов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...