2013-12-13 6 views
0

Я пытаюсь реализовать Apache Shiro CacheManager interface. Его единственный метод имеет следующую подпись:Параметр типа Java путаница

<K,V> Cache<K,V> getCache(String name) throws CacheException 

кажется крайний левый <K, V> параметр типа эффективно говорит компилятору, что K и V являются «типы». Мой вопрос таков: как я могу вернуть экземпляр этого типа? Когда я пытаюсь следующий код, Eclipse жалуется, что K и V не могут быть разрешены к типам:

public class ShiroGuavaCacheManager implements CacheManager 
{ 
    private Cache<K, V> cache; // <--- The compiler complains here 

    @Override 
    public <K, V> Cache<K, V> getCache(String name) throws CacheException 
    { 
     return (cache != null) ? cache : new ShiroGuavaCache<K, V>(); 
    } 
} 
+0

Если вы хотите определить свой собственный класс, который имеет элемент класса с параметризованными типами, вам нужно сделать класс параметризованным, т.е. 'Открытый класс ShiroGuavaCacheManager реализует CacheManager' ... В этом случае вы, вероятно, захотите удалить первый' 'из объявления' getCache'; вам не нужно параметризовать метод с теми же параметрами, которые вы используете для этого класса. Если вы понятия не имеете, о чем я говорю, и вам нужно объяснение о том, что такое дженерики, сообщите нам об этом. – ajb

ответ

1

В вашем ShiroGuavaCacheManager классе, K и V не определены. Так что если вы хотите, чтобы сделать ShiroGuavaCacheManager родовое, было бы что-то вроде

public class ShiroGuavaCacheManager<K,V> implements CacheManager 
{ 
    private Cache<K, V> cache; // without the class level K,V definitions, K and V are not known types 

    @Override 
    public Cache<K, V> getCache(String name) throws CacheException 
    { 
     return (cache != null) ? cache : new ShiroGuavaCache<K, V>(); 
    } 
} 

Тогда вы можете создать new ShiroGuavaCacheManager<String,String>(), например.



Когда у вас есть метод, который определяет типы, как следующее (как в оригинальном классе):

public <K, V> Cache<K, V> getCache(String name) 

Это работает, потому что вы решили, что K и V основаны на том, что вы назначаете его к. Таким образом, вы могли бы сделать

Cache<String,String> = getCache("mycache"); 

Они просто известны как общие методы http://docs.oracle.com/javase/tutorial/java/generics/methods.html

+0

Это работает, но это приводит к предупреждению: «Тип безопасности: тип возврата Кэш для getCache (String) от типа ShiroGuavaCacheManager нуждается в необработанном преобразовании, чтобы соответствовать Cache из типа CacheManager." Я могу добавить @SuppressWarnings («unchecked»), но каковы последствия этого? –

+1

Это потому, что вы изменили определение 'getCache', так как вы больше не определяете общие переменные inline с помощью метода, и они неявно являются' Object'. Я думаю, что если вы попробуете поставить K, V обратно до определения getCache, компилятор будет жаловаться на то, что вы переопределяете K и V (но вы можете попытаться убедиться). Я не думаю, что для этого есть простой способ обхода, но я не специалист по дженерикам, поэтому, возможно, кто-то еще может добавить к этому. –

Смежные вопросы