我有点困惑。

我有一个类,它不是集合,但确实引用了通用对象:

    public class XClass<E extends AnInterface>{

        E instanceobject;

        public void add(E toAdd){}
    }

    public interface AnInterface{}

    public class A implements AnInterface{}

    public class B implements AnInterface{}

我相信我读过某处(如果声明XClass实例时)要使用<? extends AnInterface>(如果您想同时在通用对象中使用多个子类型,而<T extends AnInterface>仅允许您在该对象中使用一种子类型)。一次通用类?

但是,我只能使用:
    XClass<AnInterface> xc = new XClass<AnInterface>();

    A a = new A();
    B b = new B();

    xc.add(a);
    xc.add(b);

这样,我可以将Supertype的多个子类型传递给泛型类……

我看不到使用“?”的目的使用接口作为通用参数有什么问题吗?

最佳答案

之所以可以同时添加AB类型的对象,是因为您使用接口对XClass进行了参数化,因此添加两个实现该接口的不同类没有错。

另一方面,如果您将XClass定义为:

XClass<A> xc = new XClass<A>();

那么表达式xc.add(b);将给出编译错误,因为所有添加的对象必须具有与声明的类型相同的类型,在这种情况下为A。

例如,如果您声明xc为:
XClass<? extends AnInterface> xc = new XClass<AnInterface>();
然后添加ab不再合法,因为我们所知道的唯一是xc是AnInterface的某些未知但已修复的子类型,并且无法知道该未知类型是A还是B或其他。

但是,假设您正在编写一种接受XClass类型的方法,可以对以前添加的元素进行迭代。您唯一的限制(出于示例考虑)是项目扩展了AnInterface,您不在乎实际的类型是什么。

您可以像下面这样声明此方法:
public static void dummyMethod(XClass<? extends AnInterface> dummy){
//do stuff here, all the elements extend (implement in this case), AnInterface, go wild.
}

现在,您可以将诸如XClass<A>XClass<B>XClass<AnInterface>之类的任何内容传递给此方法,它们都将是有效的。

请记住,由于上述相同的原因,您无法将其添加到传递的对象中。我们不知道未知类型是什么!
public static void dummyMethod(XClass<? extends AnInterface> dummy){
//do stuff here, all the elements extend (implement in this case), AnInterface, go wild.
    dummy.add(new A()); //you can't do this, we have no idea what type ? stand for in this case
}

07-28 03:18