简体   繁体   English

如何在具有相同数据类型参数的另一个泛型类(或接口)中使用泛型类(或接口)而无需强制转换

[英]How to use generic class (or interface) in another generic class (or interface) with the same data type parameters without casting

I need the Cache class that keep the <TKey key, TValue value> pairs. 我需要保留<TKey key, TValue value>对的Cache类。 And it is desirable that TKey can be any class that supports Serializable interface and TValue can be any class that supports Serializable and my own ICacheable interfaces. 并且希望TKey可以是任何支持Serializable接口的类,而TValue可以是任何支持Serializable和我自己的ICacheable接口的类。

There is another CacheItem class that keeps <TKey key, TValue value> pair. 还有另一个CacheItem类,该类保持<TKey key, TValue value>对。 I want the Cache class has the void add(CacheItem cacheItem) method. 我希望Cache类具有void add(CacheItem cacheItem)方法。 Here is my code: 这是我的代码:

public class Cache<TKey extends Serializable, 
   TValue extends Serializable & ICacheable >
{
 private Map<TKey, TValue> cacheStore = 
     Collections.synchronizedMap(new HashMap<TKey, TValue>());

 public void add(TKey key, TValue value)
 {
  cacheStore.put(key, value);
 }

 public void add(CacheItem cacheItem)
 {   
  TKey key = cacheItem.getKey();
  //Do not compiles. Incompatible types. Required: TValue. Found: java.io.Serializable
  TValue value = (TValue) cacheItem.getValue();
  //I need to cast to (TValue) here to compile
  //but it gets the Unchecked cast: 'java.io.Serializable' to 'TValue'
  add(key, value);
 }
}

In another file: 在另一个文件中:

public class CacheItem<TKey extends Serializable, 
  TValue extends Serializable & ICacheable>
{
 TKey key;
 TValue value;

 public TValue getValue()
 {
  return value;
 }

 public TKey getKey()
 {
  return key;
 }
}

Is there anything I could do to avoid casting? 我有什么办法可以避免投放?

使您的add方法签名如下所示:

public void add(CacheItem<TKey, TValue> cacheItem)
    public void add(CacheItem<TKey, TValue> cacheItem) {
    TKey key = cacheItem.getKey();
    TValue value = cacheItem.getValue();
    add(key, value);
}

You are using the raw type on CacheItem. 您正在CacheItem上使用原始类型。 Try this signature: 试试这个签名:

  public void add(CacheItem<TKey, TValue> cacheItem)

That will require that the CacheItem have the same generic parameters as the Cache. 这将要求CacheItem具有与Cache相同的通用参数。

First, you could make ICacheable extends Serializable , that would simplify your code. 首先,您可以使ICacheable扩展Serializable ,从而简化代码。


Could you try to parameterize the method add's parameter ? 您可以尝试参数化方法add的参数吗?

public class Cache<TKey extends Serializable, 
   TValue extends Serializable & ICacheable >
{
 ...
 public void add(CacheItem<TKey, TValue> cacheItem)
 {   
  TKey key = cacheItem.getKey();
  TValue value = cacheItem.getValue();
  add(key, value);
 }
}

Because CacheItem is a parameterized class, most references to it should use the parameters. 由于CacheItem是参数化的类,因此对其的大多数引用都应使用参数。 Otherwise, it still has unresolved types, and you are confronted to casts . 否则,它仍然具有无法解析的类型,并且您将面临casts

I think you should change your class like below 我想你应该像下面这样改变你的班级

public class Cache<TKey extends Serializable, 
   TValue extends Serializable & ICacheable >
{
 private Map<Serializable, Serializable> cacheStore = 
     Collections.synchronizedMap(new HashMap<Serializable, Serializable>());

 public void add(Serializable key, Serializable value)
 {
  cacheStore.put(key, value);
 }

 @SuppressWarnings("unchecked")
public void add(CacheItem cacheItem)
 {   
  Serializable key = cacheItem.getKey();
  //Do not compiles. Incompatible types. Required: TValue. Found: java.io.Serializable
  Serializable value = cacheItem.getValue();
  //I need to cast to (TValue) here to compile
  //but it gets the Unchecked cast: 'java.io.Serializable' to 'TValue'
  add(key, value);
 }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM