我有一个通用类,旨在保留不同类型属性的值。我想提供一种类型安全的方法来设置属性值,这样就不可能为属性分配错误类型的值。
我定义了一个为所有属性类型实现的接口(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 :
- 让您的属性
了解它将支持的实际类型 - 在 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/