Java泛型如何约束两个类型参数间的关联关系
解决方案
Java 不支持你尝试的T<K>这种高阶类型参数声明语法,要实现K和T的类型绑定,只需要在声明T的上界时,明确指定其继承的Cacheable的泛型参数为当前接口的K即可。
正确的接口定义
import java.io.Serializable; import java.util.Optional; /** * 存储可缓存对象的缓存接口 * @param <K> 缓存键类型,必须可序列化 * @param <T> 缓存值类型,必须是键类型为K的Cacheable实现类 */ public interface Cache<K extends Serializable, T extends Cacheable<K>> { Optional<T> get(K key); T put(T cacheable); }
类型安全说明
- 该定义会在编译期强制约束:所有存入缓存的
T类型实例,调用getKey()的返回值必须和缓存声明的键类型K完全一致,不存在类型安全漏洞。 - 你之前尝试的
public interface Cache<K, T<K> extends Cacheable<K>>写法无法通过编译,是因为Java泛型的类型参数本身不能再声明形式类型参数,该语法属于其他支持高阶泛型语言的特性,Java目前不支持。
使用示例
以键类型为Long的User缓存对象为例:
// 可缓存对象实现 public class User implements Cacheable<Long> { private Long id; private String username; @Override public Long getKey() { return id; } // 省略构造方法、其他属性的getter/setter } // 绑定类型的User缓存接口,编译期自动校验类型匹配 public interface UserCache extends Cache<Long, User> { // 该接口下的put方法仅能接收User类型实例 // get方法仅能接收Long类型的键,不会出现类型不匹配问题 }
如果尝试传入键类型不匹配的类,编译器会直接报错拦截:
// 该Config类的键类型为String public class SysConfig implements Cacheable<String> { @Override public String getKey() { return "sys_config"; } } // 以下代码编译直接失败,因为SysConfig的键类型为String,和Cache声明的Long类型不匹配 public interface WrongCache extends Cache<Long, SysConfig> {}
内容的提问来源于stack exchange,提问作者kembhootha
相关产品推荐
相关产品推荐

