Java泛型-无法应用于给定类型

提问

我有一些类似的代码:

public class Main {

    private static abstract class Bar {}

    private static class SubBar extends Bar {}

    private static abstract class Baz<T extends Bar> {

        private T t;

        public void setT(T t) {
            this.t = t;
        }

    }

    private static class SubBaz extends Baz<SubBar> {}


    private void foo(Baz<? extends Bar> baz, Bar bar) {
        baz.setT(bar);
    }
 }

导致错误:

error: method setT in class Baz<T> cannot be applied to given types;
required: CAP#1
found: Bar
reason: actual argument Bar cannot be converted to CAP#1 by method invocation conversion
where T is a type-variable:
T extends Bar declared in class Baz
where CAP#1 is a fresh type-variable:
CAP#1 extends Bar from capture of ? extends Bar

我不明白为什么. setT方法应该接受扩展Bar的内容,而我要传递Bar类的内容.

最佳答案

The method setT should accept something that extends Bar and I am passing something of class Bar.

这正是问题所在:&lt ;?扩展Bar>表示“某些未知类型,它是Bar或其子类”.由于您不知道它是哪种类型,因此实际上不可能在该上下文中调用setT(),除非使用null参数.

这将按预期工作:

private void foo(Baz<Bar> baz, Bar bar) {
    baz.setT(bar);
}

我敢肯定,Stackoverflow上存在数百种此类问题.似乎几乎每个程序员一开始都会误解什么?通配符用于并错误地使用它.

在您的Bar类具有公共T getT()方法的情况下,它的实用程序.类型为Baz&lt ;?的变量扩展Bar>可以同时容纳Baz< Bar>的对象和Baz< SubBar&gt ;,您可以在其上调用getT()以获得Bar(或某些子类)的东西,并且可以像这样使用.