Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有依赖泛型类型的泛型类,不能专门化吗?_Java_Generics - Fatal编程技术网

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();
}
}
  • 到目前为止没有问题,尽管我不确定是否需要这两种泛型类型。理想情况下,我更愿意使用Wrapper>并能够访问F和V。我认为这是不可能的,而上面的方法是正确的吗

  • 现在才是真正的问题

  • 我想为LabelField类型提供一个更具体的构造函数,如下所示:

    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