泛型 - 我错过了什么或者有什么意义?

时间:2012-07-11 13:19:33

标签: java generics

我有以下代码:

public class AClass<X extends AnInterface> implements AnotherInterface {

    public AClass(X x){
    }

}

为什么我会使用X作为构造函数参数类型,当我可以用AnInterface替换它时?当然,他们的意思相同,任何属于AnInterface

的子类型

我试图将所有参数类型保持为通用,并且仅在通用参数声明中提及接口名称,例如“X extends AnInterface”但遇到问题,因为它说的是我传入的值,类型为AnInterface,不等于X型。

编辑:

public void<X extends AnInterface> myMethod(){


    AnInterface b = new ADiffClass();
    AnotherInterface a = new AClass(b);
}

public class ADiffClass<X extends AnInterface> implements AnInterface {

    public ADiffClass(){
    }

}

这是我遇到问题的地方,我得到一个编译错误,说b的类型是AnInterface,而且AClass的构造函数中所需的类型是X.

5 个答案:

答案 0 :(得分:6)

假设您遇到这种情况:

public class AClass<X extends AnInterface>{

    public AClass(X x){
        ...
    }

    public X getIt() {
        ...
    }

}

创建对象的人将有一个相应的接口,在这种情况下它会很有用。

例如:

// supposing DefaultAnInstance is an implementation of AnInstance interface
DefaultAnInterface obj = new DefaultAnInterface();
AClass<DefaultAnInterface> instance = new AClass<DefaultAnInterface>(obj);
...
// for the user getIt will return an objecct of type DefaultAnInterface
DefaultAnInterface obj = instance.getIt(); // there is no need to cast it to DefaultAnInterface

答案 1 :(得分:6)

如果你声明一个这样的变量:

private AClass<Foo> a;

以下内容有效:

 a = new AClass<Foo>(new Foo());

但是以下不是:

 a = new AClass<Foo>(new Bar());

(假设FooBarAnInterface}的两种实现。

在这种情况下,这就是泛型:将类型限制为实现(或扩展)AnInterface的特定类型。

答案 2 :(得分:0)

为什么要尝试扩展接口?你的意思是实现它吗?我认为问题是你正在使用一个你应该使用接口的类。如果你希望能够传递多个类的东西,那正是接口的用途。

答案 3 :(得分:0)

鉴于你的AClass,你可能希望它不像普通泛型一般 - 它不能处理任何类型,比如LinkedList这样的泛型,但是你希望它能够处理很多类。

例如,假设您有一个SelfSortingList类,它是通用的。它的所有对象都需要具有可比性才能进行排序。但是你不希望允许同时实现Comparable的Widgets和Levers在同一个列表中;那是没有意义的,他们对可比较的特定实现可能反映了这一点。

所以你要说的是,“我希望我的SelfSortingList能够保存相同类型的对象,但它们必须具有可比性。”这就是为什么你在类头SelfSortingList中同时拥有一个类型参数(X)和对X的限制(扩展Comparable)。

答案 4 :(得分:0)

没有理由你不能。但是,这可能会破坏您的泛型类的其余部分:

public class AClass<X extends AnInterface> {
    private X anInterface;
    public AClass(AnInterface anInterface) {
       // Not legal.  You'd have to narrow cast to X
       this.anInterface = anInterface;
    }
}

所以,你总是可以将“anInterface”的声明改为AnInterface而不是X.但是,泛型并没有给你任何东西,因为你不再指X了

public class AClass<X extends AnInterface> {
    private AnInterface anInterface;
    public AClass(AnInterface anInterface) {
       // Not legal.  You'd have to narrow cast to X
       this.anInterface = anInterface;
    }
}

X在哪里使用?您将插入未使用的通用参数。

然后还有另一个答案中提到的构造函数类型安全问题。

这两个构造者并不意味着同样的事情:

public AClass(AnInterface anInterface) { ... }
public AClass(X anInterface) { ... }

第一个意味着您可以拥有与AnInterface兼容的任何类(即实现或扩展它)。第二个意味着你可以拥有任何与所提供的泛型参数兼容的类,这些参数可能比AnInterface更具特异性。有人使用上面这个例子:

public class Int1 implements AnInterface { ... }
public class Int2 implements AnInterface { ... }
public class Int3 extends Int1 { ... }

所以如果你有:

AClass<Int1>  --> it could accept either Int1 or Int3, but not Int2 in the constructor
AClass<Int2>  --> it could accept only Int2 in the constructor
相关问题