1

I am trying implement EhCache.

As my setup of CacheManger class uses generics thus I want my cache manager instance to be generics also.

Initially I tried using array but that came to dead end as there is no generics sol for array types.

If anyone can help me understand how does generics works with list that would be great.

What i can think of at this time is putting List.class and then type cast to concrete types. but i can very well be wrong do suggest if this approach also can be improved.

public class CacheManager<Dao extends DaoImpl,Pojo extends PozoImpl> {

    Class<Dao> clazz = null;
    Class<Pojo> _clazz_pojo = null;
    // < I tried Pojo[] instead of List but its not posibble with generics >
    Cache<String, List<Pojo>> _cache = null;

    // get cacheManager singleton obj
    public static CacheManager cacheManager = EhCacheInstance.ehInstance.getInstance();

    public CacheManager(Class<Dao> clazz,Class<Pojo> _clazz_pojo) {
        // get cache
        // < How do we init List here? >
        _cache = cacheManager.getCache(_clazz_pojo.getName(), String.class, ? ); 

        // init
        if(_cache == null){
            _cache = cacheManager.createCache(_clazz_cargo.getName(), 
                    CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, ? , ResourcePoolsBuilder.heap(10)));
        }

        // assigment
        this.clazz = clazz;
        this._clazz_cargo = _clazz_cargo;
    }
}

Thanks in advance.

JBaba
  • 590
  • 10
  • 30

1 Answers1

4

It is a generic quirk. There is no clean solution. Basically, as soon as you have something similar to <T> T get(Class<T>) you are doomed. It is impossible to do List<String> s = get(List.class) easily.

You need to cast somewhere and suppress the warning. In your case, I would probably do something like:

public CacheManager(Class<Dao> clazz, Class<Pojo> _clazz_pojo) {
    Class<List<Pojo>> valueClass = cast(List.class);
    _cache = cacheManager.getCache(_clazz_pojo.getName(), String.class, valueClass);

    if(_cache == null){
        _cache = cacheManager.createCache(_clazz_pojo.getName(),
                CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, valueClass,
                        ResourcePoolsBuilder.heap(10)));
    }

    // ...
}

@SuppressWarnings("unchecked")
private <T, V> Class<V> cast(Class<T> t) {
    return (Class<V>) t;
}
Henri
  • 5,551
  • 1
  • 22
  • 29
  • Sure there is, why not use type tokens ("Gafter's Gadget") like everyone else does (guice, jackson, jaxrs, guava, etc)? It's been solved since at least 2006. – Ben Manes Jan 06 '19 at 08:42
  • For many reasons but I'm not here to start an API war. Just to help the guy. – Henri Jan 07 '19 at 17:11
  • Oh, it's not a flame war but an honest question. There are lots of good reasons for different API design choices and those should be owned. However it is not the language's fault, hence the challenge to that assertion. – Ben Manes Jan 07 '19 at 18:37
  • :-) I've seen frameworks using it or not. I'm not behind the Ehcache API. JCache doesn't have it either. EasyMock and Mockito are not. But I thought about it. And finally decided to be sloppy instead in the typing to make it easier for users. The TypeReference forces to have anonymous inner classes all around. It's an ugly workaround due to the lack of RTTI. But I think I would have preferred Java to let those pass without warning. But I could right for a long time about it. – Henri Jan 07 '19 at 20:32
  • @Henri Yup that's why nobody answered it for three days and I already went ahead with what you suggested. But I was thinking that JAVA can still pull cat out the bag which i don't know. – JBaba Jan 08 '19 at 20:28
  • sadly no, it's just the way it is. – Henri Jan 09 '19 at 21:33