我在解释/理解Java列表的通用类型时遇到困难:
List<? extends Command> myVar = client.performAction(actionParams);
如何调用通用类型? extends Command
,就像它的名称一样?这到底是什么类型?它是Command
对象吗?还是这意味着它仅接受扩展Command
的类?使用这种结构的优势是什么?这种结构在什么Java版本中集成?
答案 0 :(得分:7)
Upper-bounded通配符用于放宽可以使用的对象的类型限制。在这种情况下,您接受扩展/实现 Command
类型的所有内容。
答案 1 :(得分:2)
关于List<? extends Command>
的重点是它是抽象类型。您不能写new List<? extends Command>()
并期望创建一些东西。有两个原因。
List
是一个接口,具有ArrayList
,LinkedList
等具体实现。Command
的子类型的任何类型,包括Command
本身”。这意味着List<? extends Command>
类型的变量可以引用任何这些具体类型的对象
ArrayList<Command>
LinkedList<SpecialCommand>
CopyOnWriteArrayList<ImportantCommand>
和许多其他组合。当然假设SpecialCommand
和ImportantCommand
是Command
的子类型。
在创建该变量将要引用的对象时,需要明确说明其具体类型。例如
List<? extends Command> myCommandList = new ArrayList<SpecialCommand>();
完成此操作后,当然可以在List
上调用一些常用的myCommandList
方法,例如
Command firstCommand = myCommandList.get(0);
这很好,因为我们知道列表中的任何对象,它们都将是某种类型的Command
。但是你不能做类似的事情
SpecialCommand mySpecialCommand = new SpecialCommand();
myCommandList.add(mySpecialCommand);
因为编译器无法知道您正在向列表中添加正确的对象。此时,myCommandList
可以是LinkedList<ImportantCommand>
或类似名称,并且编译器需要阻止向其添加SpecialCommand
。
这意味着,只有在其中有变量where时,才应使用类型List<? extends Command>
ArrayList
,LinkedList
等)Command
这意味着您通常不会将其用于局部变量或字段。它更可能是方法参数,传入的东西可能是LinkedList<ImportantCommand>
或其他任何东西;但是您在该方法中要做的就是从列表中删除对象,并对它们执行Command
类型的操作。
自Java 5以来,泛型就一直使用Java,包括通配符。
答案 2 :(得分:1)
如何调用通用类型
? extends Command
,例如 的名字吗?
这些被称为通用wildcards。
此类型究竟是什么?它是
Command
对象吗?
它仅用于在编译时检查变量分配。在运行时,泛型为erased,并解释为List myVar = client.performAction(actionParams);
这是否意味着它仅接受扩展
Command
的类?
您只能说List<Command> myVar = client.performAction(actionParams);
,它将接受Command
类型或命令子类的任何对象。
List<? extends Command> myVar
控制变量分配。因此,您只能将以下泛型分配给myVar
。假设SubCommand扩展了Command,以下分配都是有效的:
myVar = new ArrayList<SubCommand>
myVar = new ArrayList<Command>
当使用通配符通用声明集合时,它也可以成为read-only。例如myVar.add(new SubCommand());
将导致编译器错误。
使用这种结构对我有什么好处?
最初,Java不包含泛型。它是在Java 5.0中添加的,以允许对Java集合进行类型限制,例如List
,Set
,Map
等。
答案 3 :(得分:1)
既然您一次问了很多问题,让我简要介绍一下:
Object
对象的灵活数据结构,但是必须cast
转换为最终类型并在代码中的很多地方使用instanceOf
。因此引入了泛型以缓解此问题并简化代码。?
是通配符,List<? extends Command>
将限制List
包含扩展或实现< / strong>类或接口Command
强制对对象接口施加约束。 答案 4 :(得分:1)
List<? extends Command>
被称为上限通配符(许多答案已经解决了此问题)。通常,没有人会这样宣布自己的名单;主要用于方法(更常见的是静态方法)。
List<? extends Command>
是指包含{em>一种特定类型的{em> {em}(即一个特定的子类)的列表。由于它是未知的子类类型,因此在编译时,您将无法添加任何内容。您的IDE可能会将Command
方法解析为add
。
add(null e)
尽管看似相似,但它指的是可以容纳任何内容的列表,只要它是List<Command>
(或从Command
继承而来)即可。
示例:
Command
使用时间示例:
List<? extends Command> commands = new ArrayList<FooCommand>();
commands.add(new FooCommand()); // Not allowed at compile time
List<Command> commands = new ArrayList<>();
commands.add(new FooCommand());
commands.add(new BarCommand());