Java 具有依赖泛型类型的泛型类,不能专门化吗?
我目前正在使用以下类型:Java 具有依赖泛型类型的泛型类,不能专门化吗?,java,generics,Java,Generics,我目前正在使用以下类型: // A Field whose values are of type V. interface Field<V> { public V getValue(); } // A Field whose values are of type V and that has a LabelProvider for those values. interface LabelField<V> extends Field<V> {
// A Field whose values are of type V.
interface Field<V> {
public V getValue();
}
// A Field whose values are of type V and that has a LabelProvider for those values.
interface LabelField<V> extends Field<V> {
public LabelProvider<V> getLabelProvider();
}
//值为V类型的字段。
接口字段{
public V getValue();
}
//一种字段,其值为V类型,并且具有这些值的LabelProvider。
接口LabelField扩展字段{
公共LabelProvider getLabelProvider();
}
这些来自图书馆,我无法更改。这可能不相关,但LabelProvider基本上是一个将V类型的值转换为字符串的类
现在我想创建一个类,该类提供如下类似的接口:
// A Wrapper class for Fields of values V
interface IWrapper<V, F extends Field<V>> {
public F getField();
public V getValue();
public String getLabel();
}
//值为V的字段的包装类
接口断路器{
公共F getField();
public V getValue();
公共字符串getLabel();
}
该类将包装一个字段,并允许其用户从字段中检索值,但还提供其他功能,包括检索标签。以下是我所拥有的:
public class Wrapper<V, F extends Field<V>> {
private F field;
private LabelProvider<V> labelProvider; // Converts from V to String
// Since we have no guarantee that F has a LabelProvider, one is explicitely supplied.
public Wrapper(F field, LabelProvider<V> labelProvider) {
this.field = field;
this.labelProvider = labelProvider;
}
private String getLabel() {
return labelProvider.getLabel(field.getValue());
}
public F getField() {
return field;
}
public V getValue() {
return field.getValue();
}
}
公共类包装器{
私有F场;
私有LabelProvider LabelProvider;//从V转换为字符串
//因为我们不能保证F有一个LabelProvider,所以我们明确提供了一个。
公共包装器(F字段,LabelProvider LabelProvider){
this.field=字段;
this.labelProvider=labelProvider;
}
私有字符串getLabel(){
返回labelProvider.getLabel(field.getValue());
}
公共F getField(){
返回字段;
}
public V getValue(){
返回字段.getValue();
}
}
public Wrapper(LabelField<V> labelField) {
// Use the field's own label provider
this(labelField, labelField.getLabelProvider());
}
public包装器(LabelField-LabelField){
//使用字段自己的标签提供程序
这是(labelField,labelField.getLabelProvider());
}
在这种情况下,可以从字段中提取labelprovider。但是编译器不喜欢这样,我得到以下错误:
The constructor Wrapper<V,F>(LabelField<V>, LabelProvider<V>) is undefined
构造函数包装器(LabelField、LabelProvider)未定义
尽管此方法使用相同的类型,但编译:
public static <X> void test(LabelField<X> lf) {
LabelProvider<X> lp = lf.getLabelProvider();
new Wrapper<X, LabelField<X>>(lf, lp);
}
公共静态空隙试验(LabelField lf){
LabelProvider lp=lf.getLabelProvider();
新包装(lf、lp);
}
为什么第二个构造函数不编译
这里有一个SSCE:
F
可以是扩展字段的任何类型,并且该类型不一定是LabelField
例如,如果您创建一个实现字段
的类FooField
,并使用包装器
,则LabelField
构造函数将不匹配
您可以通过这种方式简化包装器(这也回答了您的第一点):
公共类包装器{
私人领域;
私有LabelProvider LabelProvider;//从V转换为字符串
//因为我们不能保证F有一个LabelProvider,所以有一个是明确的
//供应。
公共包装器(字段,LabelProvider LabelProvider){
this.field=字段;
this.labelProvider=labelProvider;
}
公共包装器(LabelField LabelField){
//使用字段自己的标签提供程序
这是(labelField,labelField.getLabelProvider());
}
私有字符串getLabel(){
返回this.labelProvider.getLabel(this.field.getValue());
}
公共字段getField(){
返回此.field;
}
public V getValue(){
返回此.field.getValue();
}
}
对于字段
使用“常规”多态性而不是泛型,您将泛型和继承混合在一起
只能使用V
参数化:
public class Wrapper<V>
为什么不包装labelfields,因为它本身就是字段?我必须支持其他类型的字段,而不是labelfields。另外:我已经解决了业务问题,但我有兴趣了解如何以及为什么不进行类型检查。这就是我实际实现的是,但是我们失去了字段类型中的泛型(因此在调用getField()时需要强制转换)。在您看来,没有办法做得更好了?@ARRG在这种情况下,您可以通过对包装器进行子类化来进行专门化
public class Wrapper<V>
Field<V>
F