当前位置: 首页 > 面试题库 >

为什么不能将包含通用类型的通用类型分配给通配符类型的通用类型的类

蔚俊人
2023-03-14
问题内容

抱歉,标题似乎令人困惑,但请按示例进行操作。

假设我有一些带有通用类型参数的Java类:

public class GenericClass<T> {
}

我可以创建一个类型为存储对象的变量,并将通用参数设置为String。Java还允许我将该变量分配给另一个变量,但将通用参数设置为通配符<?>类型:

GenericClass<String> stringy = ...
GenericClass<?> generic = stringy; // OK

但是,在使用具有泛型参数的类时,如果将该参数的类型设置为泛型,则无法将该类的对象分配给相同类型/泛型的类型,后者(内部/嵌套)参数是通配符类型<?>

GenericClass<GenericClass<String>> stringy = ...
GenericClass<GenericClass<?>> generic = stringy; // Compile Error

// And just in case that is confusing, a more
// realistic example involving Collections:
List<GenericClass<String>> stringy = ...
List<GenericClass<?>> generic = stringy; // Compile Error

具体的编译错误是:

Type mismatch: cannot convert from List<GenericClass<String>> to List<GenericClass<?>>

凭直觉,我认为所讨论的作业应该不是问题。那么为什么这个分配有问题呢?


问题答案:

您面临的问题称为协方差。

List<GenericClass<String>> stringy = ...
List<GenericClass<?>> generic = stringy;
generic.add(new GenericClass<Integer>());

如果这不是编译错误,那么最后一行代码将是可能的。

您可以通过以下方法解决错误:

 List<? extends GenericClass<?>> generic = stringy;

但您也不能使用,add因为您真的不知道什么? extends GenericClass<?>(再次是协方差)。在这种情况下,您只能通过List进行枚举并期望GenericClass<?>



 类似资料:
  • 问题内容: 我是Generic的新手,我的问题是:两个函数之间有什么区别: 功能1: 功能2: 问题答案: 第一个签名说:是一个ES列表。 第二个签名说:是某种类型的实例的,但是我们不知道类型。 当我们尝试更改方法时,区别变得明显,因此它需要第二个参数,该参数应添加到方法内部的列表中: 第一个效果很好。而且你不能将第二个参数更改为可以实际编译的任何参数。 实际上,我发现了一个更好的区别说明: 一个

  • 问题内容: 考虑以下方法: 和 这两种方法有什么区别?如果没有差异,为什么要使用第二个? 问题答案: 不允许您在列表中添加对象。请参阅下面的程序。这是我们传递给method的特定列表类型。 特定方式,列表是使用特定类型创建的,并传递给method 。不要与 单词 混淆。 具体可以是任何普通对象,例如Dog,Tiger,String,Object,HashMap,File,Integer,Long

  • 问题内容: 我在某处看到了这种模式: 通过将新类型指定为泛型的实际类型来扩展泛型,此结构有点不寻常。有什么用?此模式有名称吗?有其他替代方式吗? 示例:https://code.google.com/p/selenium/wiki/LoadableComponent 跳到: 编辑:阅读响应后,似乎我需要改变编译器对类型检查的理解。在我的脑海中,我有这种模式的牛肉是,如果两个A需要相同,那么有没有办

  • 在试图理解java泛型类型和通配符“?”的用法时,我尝试了以下方法: 我得到以下编译错误(使用Oracle JDeveloper作为IDE): 为什么上面的代码不能编译,而赋值却可以呢?另外,如果我想调用,什么是可接受的参数值?

  • Locality Node Endpoint Metadata RuntimeUInt32 HeaderValue HeaderValueOption ApiConfigSource ApiConfigSource.ApiType (Enum) AggregatedConfigSource ConfigSource TransportSocket RoutingPriority (Enum) Re

  • 问题内容: 在以下示例中: 为什么对second(b)的调用有效,但对third(a)的调用却无效 ? 我收到以下错误: 问题答案: 如果您希望能够使用自变量进行调用,则需要将签名更改为此: 将上面的工作,因为不像,是兼容。这样想: 推理很简单。如果你有 然后,如果您 可以这样 调用该方法: