2015-08-14 3 views
1

Я пытаюсь реализовать Guava Cache.Typecasting A <X,Y> to A <Object, Object>

Мой Cache Объект:

Cache<String,MyObject> cache = initCache(); 

И GuavaCache конструктор выглядит следующим образом:

GuavaCache(String name, com.google.common.cache.Cache<Object, Object> cache) 

Делать это:

GuavaCache options = new GuavaCache("guava_cache",cache); 

дает ошибку:

Cache<String,OptionMap> cannot be converted to Cache<Object,Object> 

Я пробовал <Object,Object> cache, но это не работает.

Cache представляет собой интерфейс:

public interface Cache<K, V> 

GuavaCache: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/guava/GuavaCache.html

это то, что делает initCache:

return CacheBuilder.newBuilder() 
       .expireAfterAccess(200, TimeUnit.SECONDS) 
       .build(new CacheLoader<String, MyObject>() { 
        @Override 
        public MyObject load(String key) throws Exception { 

         return new MyObject(loadFromRedis()); 
        } 
       }); 
+1

Является ли GuavaCache определенным вами классом? Было бы полезно посмотреть, как он использует объект кэша, который он задает, особенно если он должен читать или записывать на него или и то, и другое. – dfogni

+0

Из-за стирания типов типы 'Cache ' и 'Cache ' выглядят одинаково во время выполнения. Таким образом, вы должны просто использовать кеш для 'Cache ': например. 'новый кэш GuavaCache (" guava_cache ", (кеш <объект, объект>))'. Но имейте в виду, что из-за этого вы теряете безопасность типов. –

+0

@TillRohrmann: Я не могу его преобразовать. Ошибка ввода Невозможно использовать кеш для кэша

ответ

3

Короткий ответ, что ваш Cache<String, MyObject> cache является неCache<Object, Object> и поэтому вы не можете передать его конструктору, который требует Cache<Object, Object> ,

Основная проблема здесь состоит в том, что в Spring GuavaCache не в первую очередь обертка гуавы Cache, а это реализация интерфейса Spring, Cache что случается подкреплено гуавой Cache.

различие может быть немного тонким, но важным моментом является то, что контракт вы имеете дело с Spring в Cache, и этот интерфейс позволяет использовать любые Object S в качестве ключей и значений - см put(Object, Object).

Поэтому, если вы хотите использовать Spring GuavaCache, вы должны передать ему объект Guava Cache, который позволяет использовать любые ключи и значения Object. Но ваш Cache<String, MyObject> этого не позволяет. Библиотека не сломана, она намеренно закодирована таким образом, чтобы вы не передавали неправильный тип кэша в конструктор, и поэтому ваш код не будет компилироваться.

Вы видели, что вы можете выманить его, отбросив кеш до необработанного Guava Cache, но потом что произойдет, если кто-то это сделает?

options.put("key","not a MyObject"); // appears to work fine 

MyObject item = cache.get("key"); // throws a ClassCastException 

Если вы действительно хотите использовать GuavaCache вы должны уважать свой контракт, и дать ему объект подложки, который поддерживает операции, определенные в Cache. Например:

Cache<Object, Object> cache; 

и

Cache<Object, Object> initCache() { 
    return CacheBuilder.newBuilder() 
     .expireAfterAccess(200, TimeUnit.SECONDS) 
     .build(new CacheLoader<Object, Object>() { 
      @Override 
      public Object load(Object key) throws Exception { 
       return new MyObject(loadFromRedis()); 
      } 
     }); 
} 
+0

Можете ли вы дать мне окончательное решение, которое работает. Я также включил свой initCache. –

+0

@lliBtheLizard добавил пример. Нельзя использовать 'Cache ', но он вынужден по контракту 'GuavaCache' – CupawnTae

+0

Кэш абстрактный, поэтому последние две строки не будут работать. В сущности, последняя реализация CacheManager в [link] https://dzone.com/articles/spring-caching-abstraction-and также не работает. Все причины почему? –

-1

Поскольку вы не можете иметь безопасность типа, я бы просто использовать сырые типы.

Cache cache = initCache(); 
new GuavaCache("guava_cache",cache); 
+0

Уход за объяснением причины нисходящего потока? Читая комментарии, это также то, что автор закончил делать – dfogni

+0

. Вы вряд ли получите ответ на этот вопрос: большинство приводов-приводов не возвращаются. Я не спускал вниз, но я предполагаю, что причина в том, что это решение «дурачит» Java в передачу чего-то, что не является «Cache » в параметре этого типа. По крайней мере, тип параметра в 'GuavaCache' должен быть изменен, чтобы отразить то, что конструктор хочет в качестве параметра, а именно: * not *' Cache ' – CupawnTae

+0

Дженерики стираются во время выполнения, поэтому опуская их как влияние только во время компиляции, никакой код вне GuavaCache никогда не сможет использовать объект. Проблема здесь в том, что библиотека принудительно 'Object', когда они хотели'? '. Опущение дженериков - единственный разумный подход, кроме остановки использования этой библиотеки. – dfogni

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