使用类<;T>;作为Java中注释的属性

使用类<;T>;作为Java中注释的属性,java,Java,我们正试图在Java中创建一个缓存的基本实现。为此,我们创建了一个注释@Cached,定义为: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Cached { <T> Class<T> keyClass(); <V> Class<V> valueClass(); String cacheId(); }

我们正试图在Java中创建一个
缓存的基本实现。为此,我们创建了一个注释
@Cached
,定义为:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Cached {

    <T> Class<T> keyClass();

    <V> Class<V> valueClass();

    String cacheId();
}
public class CacheEntry<V> {
   private V value;
   // Some other fields used for invalidating the cache entry and accessors
}
CacheEntry
定义为:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Cached {

    <T> Class<T> keyClass();

    <V> Class<V> valueClass();

    String cacheId();
}
public class CacheEntry<V> {
   private V value;
   // Some other fields used for invalidating the cache entry and accessors
}
在上面的代码中,
cached
是方法上使用的
@cached
注释的引用,如下所示:

@Cached(keyClass = Long.class, valueClass = Person.class, cacheId = "personCache")
List<Person> findAll();
@Cached(keyClass=Long.class,valueClass=Person.class,cacheId=“personCache”)
列出findAll();
cached.valueClass().cast(value)
在这种情况下无法帮助您,主要是因为编译器无法强制执行
cached.valueClass()
cached.valueClass()兼容

帮助缓存客户端进行类型转换的最佳方法是让它们在读取时指定目标类型:

public <V> List<V> getAllCachedValues(Class<V> valueClass) {
    return cache.getCache().values().stream()
    .map(value -> valueClass.cast(value))
    .collect(Collectors.toList());
}
当然,您可以将
Class
参数添加到
getCache

Cache<Long, Banana> cacheInstance = cacheManager.getCache("personCache", 
                    Long.class, Banana.class);
Cache cacheInstance=cacheManager.getCache(“personCache”,
长类,香蕉类);
并使用实际的
实例进行验证。但是,当您可以采用第一种方法(检索时强制转换)时,这样做的意义何在。。。归根结底,调用者将最终确保类型兼容性,而注释元数据则无济于事


在我看来,
@Cached(keyClass=Long.class,valueClass=Person.class,cacheId=“personCache”)
可能有助于键入将缓存值序列化为JSON和XML等格式,并且需要原始类在缓存被命中时反序列化它们(当然,希望客户端强制转换).

但是,这是必需的,因为我们想对返回方法的值进行类型转换:您能说明您打算如何进行吗?即使可以这样做,类型参数仍然会被删除。您可能需要坚持使用
。顺便说一句,为什么不使用该方法声明的返回类型?您知道编译时的返回类型吗?您无法在运行时确定什么是
t
V
,此信息在执行时被丢弃。我非常关心编写自定义缓存机制,除非有很好的理由您不能使用现有的缓存机制。你很可能会弄错,你会在这上面花费宝贵的开发时间。是的,我确实理解这一点。但问题是,是否有其他方法来实现该要求。@Kayaman我理解您的担忧。这不是一个生产代码,只是一个爱好者,我试图学习一些设计模式和注释一起使用。
@Cached(keyClass = Long.class, valueClass = Person.class, cacheId = "personCache")
List<Banana> findAll();
@Cached(keyClass = Long.class, valueClass = Person.class, cacheId = "personCache")

//and then
Cache<Long, Banana> cacheInstance = cacheManager.getCache("personCache");
Cache<Long, Banana> cacheInstance = cacheManager.getCache("personCache", 
                    Long.class, Banana.class);