Java:将通用通配符与子类一起使用 [英] Java: using generic wildcards with subclassing

查看:89
本文介绍了Java:将通用通配符与子类一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个Foo类,一个A类和A的一些子类B.Foo接受A及其子类作为泛型类型. A和B都需要在其构造函数中使用Foo实例.我希望A的Foo属于A类型,而B的Foo属于B类型或B的超类.因此,实际上,我只希望这样:

Say I have a class Foo, a class A and some subclass B of A. Foo accepts A and its sublclasses as the generic type. A and B both require a Foo instance in their constructor. I want A's Foo to be of type A , and B's Foo to be of type B or a superclass of B. So in effect, So I only want this:

Foo<X> bar = new Foo<X>;
new B(bar);

如果X是A,B或A的子类和B的超类两者都是可能的.

to be possible if X is either A, B, or a both subclass of A and superclass of B.

到目前为止,这就是我所拥有的:

So far this is what I have:

class Foo<? extends A>{
    //construct
}


class A(Foo<A> bar){
    //construct
}

class B(Foo<? super B> bar){
    super(bar);
    //construct
}

super(...)的调用不起作用,因为<A><? super B>严格.强制这些类型时,是否可以使用构造函数(或避免通过其他方式进行代码重复)?

The call to super(...) doesn't work, because <A> is stricter than <? super B>. Is it somehow possible to use the constructor (or avoid code duplication by another means) while enforcing these types?

Foo保留了通用参数类型的元素的集合,并且这些元素和Foo具有双向链接.因此,应该不可能将A链接到Foo.

Foo keeps a collection of elements of the generic parameter type, and these elements and Foo have a bidirectional link. It should therefore not be possible to link an A to a Foo.

推荐答案

如果将A构造函数更改为:

If you change the A constructor to:

class A(Foo<? extends A> bar){
    //construct
}

它会做你想要的吗?

如果您真的想将A的构造函数限制为Foo,则需要提供另一个受保护的方法(也可以从派生类使用)来设置Foo实例. 像这样:

If you really want to limit the constructor of A to Foo then you need to provide another protected method (aka usable from derived classes) to set the Foo instance. Something like this:

public class A {

    Foo<?> foo;

    public A(Foo<A> foo) {
        setFoo(foo);
    }

    protected A() {
    }

    protected void setFoo(Foo<?> foo) {
        this.foo = foo;
    }
}

和B

public class B extends A {

    public B(Foo<? super B> foo) {
        setFoo(foo);
    }
}

现在可行:

new A(new Foo<A>());
new A(new Foo<B>()); // this fails compilation
new B(new Foo<B>());

为了正确键入A中的foo元素,您可能还需要使A成为参数化的类.

In order for foo element in A to be properly typed you might need to make A a parametrized class too.

这篇关于Java:将通用通配符与子类一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆