java - 泛型方法中类类型参数的使用

标签 java generics types

我有一个通用类,旨在保留不同类型属性的值。我想提供一种类型安全的方法来设置属性值,这样就不可能为属性分配错误类型的值。

我定义了一个为所有属性类型实现的接口(interface):

public interface Property<T> {

} 

其中类型参数T用于指定属性值的类型。然后假设类 OrderProperty 实现了这个接口(interface),属性可以这样定义

OrderProperty property1 = new OrderProperty<String>();
OrderProperty property2 = new OrderProperty<Integer>();

最初,我实现了该类来保存属性值,例如

public class Properties<K extends Property> {

    private Map<K, Object> properties = new HashMap<K, Object>();

    public <V> void set(K key, V value) {
        properties.put(key, value);
    }

}

问题是 set() 方法显然不是类型安全的,因为它不考虑属性与其值类型之间的连接,因此我可以轻松编写类似的内容

Properties orderProperties = new Properties<OrderProperty>();
OrderProperty countProperty = new OrderProperty<Integer>();
orderProperties.set(countProperty, "1");

它会编译。

类型安全的实现是

public <V> void set(Property<V> key, V value) {
    properties.put(key, value);
}

但当然它不会编译,因为 key 不是泛型类型。

我需要类似的东西

public <V> void set(K<V> key, V value) {
    properties.put(key, value);
}

但这一个在语法上是不正确的。

我想知道是否有任何方法可以完成我的需要。

最佳答案

您的 Properties 类只能支持一种类型的属性。这可能不是您想要的,即使这可行:

public class Properties<V, T extends Property<? extends V>> {
    public void set(T key, V value) {
      //...
    }
}

如果您想支持不同类型的属性,则必须手动检查属性的有效性。造成这种情况的原因是 Java 的 type erasure :

  1. 让您的属性了解它将支持的实际类型
  2. 在 Properties.set 方法中检查该类型

 

public interface Property<T> {
  public Class<T> getPropertyType();
}

public class OrderProperty<T> extends Property<T> {
  Class<T> type;
  /** This constructor is required due to type erasure, otherwise the OrderType doesn't know the property type */
  public OrderProperty(Class<T> type) {
    this.type = type;
  }
  public Class<T> getPropertyType() {
    return type;
  }
}

public class Properties<K extends Property> {

    private Map<K, Object> properties = new HashMap<K, Object>();

    public <V> void set(K key, V value) {
        properties.put(key, key.getPropertyType().cast(value));
    }

}

关于java - 泛型方法中类类型参数的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3194307/

相关文章:

java - 以贪婪的方式分配给定的数字

java - 如何在 Swing (Java) 中的现有 jPanel 上画一条线?

C# 通用方法,使用参数创建控件

c# - "is"运算符在立即窗口中对盒装值的工作方式不同

mysql - 合适的 mysql 数据类型将纬度和经度存储在单独的字段中

java - 我应该使用什么命令来使用 Windows 注册表从上下文菜单启动 jar 文件?

java - Android 开发 Eclipse - 无法创建新的 Android 项目 - Mac OS

c# - 我该如何重构这段代码?

Java泛型方法通配符不匹配问题

javascript - 返回自身的复杂函数的 Typescript 类型声明