java中的不可变类型(尤其是集合)和协方差
假设我有一个类java中的不可变类型(尤其是集合)和协方差,java,collections,immutability,Java,Collections,Immutability,假设我有一个类WidgetHolder,它保存Widget实例。在内部,我使用列表对其进行备份。我保证它是不可变的,因此在构建之后,不会向持有者添加任何小部件 WidgetHolder还公开了一个getWidgets()操作,该操作返回小部件列表的不可变视图 我希望有一个派生的SpecificWidgetHolder类,该类包含SpecificWidget实例,其getWidgets()的返回类型为Collection 我有同样的保证,即SpecificWidgetHolder构造函数接受Spe
WidgetHolder
,它保存Widget
实例。在内部,我使用列表对其进行备份。我保证它是不可变的,因此在构建之后,不会向持有者添加任何小部件
WidgetHolder
还公开了一个getWidgets()
操作,该操作返回小部件列表的不可变视图
我希望有一个派生的SpecificWidgetHolder
类,该类包含SpecificWidget
实例,其getWidgets()
的返回类型为Collection
我有同样的保证,即SpecificWidgetHolder
构造函数接受SpecificWidget
实例的集合,并且不会以任何方式修改它
鉴于WidgetHolder
和SpecificWidgetHolder
都是不可变的,证明通用不变性的常见反对意见似乎并不适用(?)
有没有一种干净的方式用Java来表达这一点
谢谢 试试这个:
public class WidgetHolder<T extends Widget>
{
public List<T> getWidgets()
{
return (widgets);
}
private List<T> widgets;
} // class WidgetHolder
public class SpecificWidgetHolder extends WidgetHolder<SpecificWidget>
{
}
公共类WidgetHolder
{
公共列表getWidgets()
{
返回(小部件);
}
私有列表小部件;
}//类WidgetHolder
公共类SpecificWidgetHolder扩展了WidgetHolder
{
}
试试这个:
public class WidgetHolder<T extends Widget>
{
public List<T> getWidgets()
{
return (widgets);
}
private List<T> widgets;
} // class WidgetHolder
public class SpecificWidgetHolder extends WidgetHolder<SpecificWidget>
{
}
公共类WidgetHolder
{
公共列表getWidgets()
{
返回(小部件);
}
私有列表小部件;
}//类WidgetHolder
公共类SpecificWidgetHolder扩展了WidgetHolder
{
}
您描述的场景非常常见:您在内部存储对象集合,并希望公开此集合的只读版本。这通常使用以下方法(以及其他集合类型的特定方法)完成:
使用特定类型,您知道该类型可分配给超类的类型:
public List<SpecificWidget> getWidgets()
在如何使用该类方面存在细微的差异。特别是,关于“特定性”的信息是否可供调用者使用。我试图在这个例子中指出这一点:
// With option 1, you only receive Widgets - even
// from a SpecificWidgetHolder
List<? extends Widget> widgets = specificWidgetHolder.getWidgets();
Widget widget = widgets.get(0);
// With option 3., you still know that a SpecificWidgetHolder
// provides a list of SpecificWidgets
List<? extends SpecificWidget> specificWidgets = specificWidgetHolder.getWidgets();
SpecificWidget specificWidget = specificWidgets.get(0);
//使用选项1,您只接收小部件-甚至
//从一个特定的WidgetHolder
List您描述的场景非常常见:您在内部存储对象集合,并希望公开该集合的只读版本。这通常使用以下方法(以及其他集合类型的特定方法)完成:
使用特定类型,您知道该类型可分配给超类的类型:
public List<SpecificWidget> getWidgets()
在如何使用该类方面存在细微的差异。特别是,关于“特定性”的信息是否可供调用者使用。我试图在这个例子中指出这一点:
// With option 1, you only receive Widgets - even
// from a SpecificWidgetHolder
List<? extends Widget> widgets = specificWidgetHolder.getWidgets();
Widget widget = widgets.get(0);
// With option 3., you still know that a SpecificWidgetHolder
// provides a list of SpecificWidgets
List<? extends SpecificWidget> specificWidgets = specificWidgetHolder.getWidgets();
SpecificWidget specificWidget = specificWidgets.get(0);
//使用选项1,您只接收小部件-甚至
//从一个特定的WidgetHolder
列表为什么不能应用通用逻辑?类似这样的WidgetHolder
和T getWidget()
方法。为什么不能应用通用逻辑?类似这样的WidgetHolder
和T getWidget()
方法。很快:)很快:)谢谢你的回答!但如果您能解释一下不可修改列表示例是如何编译的,那将是一件有趣的事情。AFAICTCollections.unmodifiableList
返回实现List
接口的类的实例,包括add
等?仅供我个人参考,这里有详细说明:谢谢你的回答!但如果您能解释一下不可修改列表示例是如何编译的,那将是一件有趣的事情。AFAICTCollections.unmodifiableList
返回实现List
接口的类的实例,包括add
等?仅供我参考,这里有详细说明:
public List<SpecificWidget> getWidgets()
public List<? extends SpecificWidget> getWidgets()
// With option 1, you only receive Widgets - even
// from a SpecificWidgetHolder
List<? extends Widget> widgets = specificWidgetHolder.getWidgets();
Widget widget = widgets.get(0);
// With option 3., you still know that a SpecificWidgetHolder
// provides a list of SpecificWidgets
List<? extends SpecificWidget> specificWidgets = specificWidgetHolder.getWidgets();
SpecificWidget specificWidget = specificWidgets.get(0);