当前位置: 首页 > 知识库问答 >
问题:

java泛型v.svs[重复]

谭敏学
2023-03-14

这可能是一个非常愚蠢的问题,但我不明白编译器为什么抱怨和编译。

我有两个非常简单的课程:

class A {
}

class B extends A {
}

现在代码是:

//block1
List<A> list = new ArrayList<>();
list.add(new A()); //ok
list.add(new B()); //ok 

//block2
List<? extends A> extendList= new ArrayList<>();
extendList.add(new A()); //not ok, why?
extendList.add(new B()); //not ok, why?

//block3
List<? super A> superList = new ArrayList<>();
superList.add(new A()); //ok
superList.add(new B()); //ok. why?

我知道它为什么起作用。

块2,我有

Error: no suitable method found for add(A)
method java.util.Collection.add(capture#1 of ? extends A) is not applicable
  (argument mismatch; A cannot be converted to capture#1 of ? extends A)
method java.util.List.add(capture#1 of ? extends A) is not applicable
  (argument mismatch; A cannot be converted to capture#1 of ? extends A)

块3,我有

我想我可能对superextends关键字有误解,我在谷歌上做了一些搜索,但我的怀疑仍然存在。

oracle通用教程中的一句话:(https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html)

The term List<Number> is more restrictive than List<? extends Number>
because the former matches a list of type Number only, whereas the 
latter matches a list of type Number or any of its subclasses.

共有3个答案

平元明
2023-03-14

列表

假设你的A动物。现在你有了一个列表

你可以从列表中获取代码,因为你知道你从列表中选择的任何东西都可以分配给动物,所以没有问题。请注意,在块3中,您无法从列表中获取任何内容,但您可以插入-反过来。

您可以在列表中插入

看看有效的Java第三版和Koltin的实际应用——是的,Kotlin,它有一个稍微不同的方法,可以帮助您更好地理解它。科特林的语言已经把所有这些都变成了干净的规则。

毛博
2023-03-14

这里有一个场景可以说明。考虑第三类:

class C extends A {
}

List<C> cList = new ArrayList<>();
List<? extends A> extendList = cList; //this is valid. Right? Yes

这样一来,失败的原因就显而易见了。如果扩展列表。如果允许添加(new A()),以下内容也必须合法:

extendList.add(new B());

但是我们会在列表中添加一个不兼容的类型(B

原因是边界:

陶腾
2023-03-14

block2:“据我所知,列表将接受类型为A或子类型为A的对象,例如B”-否!考虑一下的可能值 ,例如,它可以是类C扩展了{},这意味着aB都不符合约束条件。不能将AB添加到泛型类型为C的列表中。

块3:再次考虑的可能值:现在它可以是A或其任何超类,所以A对象(或介于两者之间的任何对象)。既然Ba的一个子类型,它当然也是a的所有超类的一个子类型。每个接受A列表也会接受B

 类似资料:
  • 我在Spring批处理StepBuilder类中看到了以下方法定义。这里第一个角括号有什么用?

  • 你能向我解释一下这里发生了什么,为什么它没有错误。 很抱歉,如果已经有类似的问题,我没有正确地表达这个问题,所以不能用谷歌搜索它

  • 问题内容: 我有一个代表文本片段的泛型类。该文本片段可能具有多种不同模式(突出显示的不同类型)中的任何一种。这些模式用枚举表示。每个项目的Enum可能不同,但是它必须实现一个接口,该接口提供了一种将其中两个结合的方法(可以突出显示并加粗显示)。所以我有一个界面: 然后我的TextFragment是文本字符串和模式的容器。但是当我尝试声明该类时: 我收到以下错误: 令牌“扩展”的语法错误,预期 根据

  • 我正在尝试覆盖子类中从父类继承抽象方法的方法。我正在尝试更改泛型返回类型,但我有点困惑。 基本泛型类: 儿童班: 实施: 我想在其中覆盖参数化方法的子视图类: 这是Eclipse抛出错误消息的地方: 注意类和接口:事件和级别: 以及继承自 的 Model 类 我试图实现的是编写更抽象的代码,因为这些类、接口将被多个类扩展(在我的例子中是不同的视图类型)。这些是抽象类:< code>BaseAdap

  • 来自Java文档:在类C中声明的实例方法m1覆盖在类A中声明的另一个实例方法m2,如果以下所有条件都为真:。。。。。m1的签名是m2签名的子签名(§8.4.2)。 方法m1的签名是方法m2签名的子签名,前提是:m1的签名与m2签名的擦除相同(§4.6)。 是对一个 如果是这样,什么是错的? EDIT1:或者如果我切换通用类型: 这种情况下有什么问题? EDIT2:我知道如何修复它,但我想了解,在这

  • 这是如何编译的: 但这并不是: 它给我以下编译错误: Impl不是抽象的,并且不会覆盖测试中的抽象方法getValue(整数) 错误:名称冲突:Impl中的getValue(T)和测试中的getValue(Integer)具有相同的擦除,但两者都不重写另一个 擦除不能确保t被整数替换吗?那么为什么第二个例子是无效的呢?