Collections.unmodifierXXX 方法是否违反 LSP? [关闭]

2024-01-12

里氏替换原则 http://en.wikipedia.org/wiki/Liskov_substitution_principle是原则之一SOLID http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29。我现在已经多次阅读这个原则并试图理解它。

这是我从中得到的,

这一原则与人们之间强有力的行为契约有关。 类的层次结构。子类型应该能够替换为 超类型而不违反合同。

我读过一些其他的articles http://www.objectmentor.com/resources/articles/lsp.pdf我也是,对这个问题的思考有点迷失。做Collections.unmodifiableXXX()方法不违反LSP?

上面链接的文章摘录:

换句话说,当通过其基类接口使用对象时, 用户只知道基础的前提条件和后置条件 班级。因此,派生对象不能期望此类用户遵守 比基类所需的前提条件更强的前提条件

为什么我这么认为?

Before

class SomeClass{
      public List<Integer> list(){
           return new ArrayList<Integer>(); //this is dumb but works
      }
}

After

class SomeClass{
     public List<Integer> list(){
           return Collections.unmodifiableList(new ArrayList<Integer>()); //change in implementation
     }
}

我无法改变的实施SomeClass返回将来不可修改的列表。编译将起作用,但如果客户端尝试以某种方式改变List返回然后它会在运行时失败。

这就是 Guava 创建单独的原因吗?不可变XXX https://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained集合接口?

这不是直接违反LSP还是我完全搞错了?


LSP 表示每个子类都必须遵守与超类相同的契约。无论情况是否如此Collections.unmodifiableXXX()因此取决于本合同如何解读。

返回的对象Collections.unmodifiableXXX()如果尝试对它们调用任何修改方法,则会抛出异常。例如,如果add()被称为,一个UnsupportedOperationException会被抛出。

什么是总承包合同add()?根据API文档 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html#add%28E%29 it is:

确保此集合包含指定的元素(可选 手术)。如果此集合由于以下原因而发生更改,则返回 true 称呼。 (如果该集合不允许重复,则返回 false 已包含指定元素。)

如果这是完整的合同,那么确实不能在所有可以使用集合的地方使用不可修改的变体。然而,该规范继续说道:

如果集合出于任何原因拒绝添加特定元素 除了它已经包含该元素之外,它还必须抛出一个 异常(而不是返回 false)。这保留了不变性 集合始终包含在此之后的指定元素 呼叫返回。

这明确允许实现具有不添加参数的代码add到集合,但会导致异常。当然,这包括收藏品客户有义务考虑这种(合法)可能性。

因此,行为子类型(或 LSP)仍然得到满足。 但这表明,如果计划在子类中具有不同的行为,则也必须在顶级类的规范中预见到。

顺便说一句,好问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Collections.unmodifierXXX 方法是否违反 LSP? [关闭] 的相关文章

  • 将处理项目移至 Eclipse

    我已经在处理项目上工作了一段时间 现在想将其移至 Eclipse 中 我已经在 Eclipse 环境中安装了 Proclipse 我有很多扩展名为 pde 的文件 然而 Proclipse 文件都以 java 结尾 所有 pde 文件都存在
  • JAVA 中的 Composer 相当于什么? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我目前从 PHP 转向 java 有没有类似的工具composer https getcomposer org 在 PHP 中用于 JAV
  • 了解 netty 通道缓冲区和水印

    我正在尝试了解网络缓冲区和水印 作为一个测试用例 我有一个 netty 服务器 它向客户端写入数据 客户端被阻止 基本上每次读取之间有 10 秒的睡眠时间 在正常 I O 下 如果接收方被阻塞 TCP 发送方将受到限制 由于流量控制 发送速
  • 垂直 ViewPager 中的动画

    我需要垂直制作这个动画ViewPager https www youtube com watch v wuE 4jjnp3g https www youtube com watch v wuE 4jjnp3g 这是我到目前为止所尝试的 vi
  • 如何准确判断 double 是否为整数? [复制]

    这个问题在这里已经有答案了 具体来说 在 Java 中 我如何确定double是一个整数 为了澄清 我想知道如何确定 double 实际上不包含任何分数或小数 我主要关心的是浮点数的性质 我想到的方法 以及我通过谷歌找到的方法 基本上遵循以
  • 获取Android库中的上下文

    我正在编写一个 Android 应用程序 它的一些功能封装在内部库中 但是 要使此功能发挥作用 库需要一个应用程序上下文的实例 为图书馆提供这种上下文的最佳方式是什么 我看到了一些选择 但没有一个有吸引力 Have my library c
  • 使用全局变量从内部函数获取空字符串

    请帮助我解决一些小问题 我确信你能做到 D 我试图在 firestore 文档 user cases information 上设置一个字段 其中包含一个字段 case number 首先我声明这个全局变量 private String c
  • “避免在公共 API 中使用库私有类型” - lint 警告,即使在说明书示例中也是如此?

    我注意到样式错误警告https dart lang github io linter lints library private types in public api html https dart lang github io lint
  • 使用 kryo 注册课程的策略

    我最近发现了 kryonet 库 它非常棒并且非常适合我的需求 然而 我遇到的一个问题是制定一种好的策略来注册所有可以转移的类 我知道我可以在每个对象中编写一个静态方法 该方法将返回它使用的所有类的列表 但我真的不想这样做 为了我自己的时间
  • 但是创建静态实用方法不应该被过度使用吗?如何避免呢? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 随着时间的推移 java项目中引入了许多实用方法来完成更复杂和简单的任务 当使用静态方法时 我们在代码中引入了紧密耦合 这使得我们的代
  • java中如何重新初始化int数组

    class PassingRefByVal static void Change int pArray pArray 0 888 This change affects the original element pArray new int
  • RxJava android mvp 单元测试 NullPointerException

    我是 mvp 单元测试的新手 我想对演示者进行一个非常基本的测试 它负责登录 我只想断言 view onLoginSuccess 这是演示者代码 public LoginPresenter LoginViewContract loginVi
  • ActiveMQ JNDI 查找问题

    尝试使用 JNDI 运行以下 ActiveMQ http activemq apache org jndi support html http ActiveMQ 20JNDI 并且我的 jboss server node lib 文件夹中有
  • 接口是否像对象一样对待?

    为什么下面的代码可以工作 interface I class A implements I public String toString return in a class B extends A public String toStrin
  • Janusgraph 0.3.2 + HBase 1.4.9 - 无法设置 graph.timestamps

    我在 Docker 容器中运行 Janusgraph 0 3 2 并尝试使用运行 HBase 1 4 9 的 AWS EMR 集群作为存储后端 我可以运行 gremlin server sh 但如果我尝试保存某些内容 我会得到粘贴在下面的堆
  • Java 8 方法签名不一致

    Java 8 为我们提供了具有很长签名的新方法 如下所示 static
  • Java 中序列化的目的是什么?

    我读过很多关于序列化的文章 以及它如何如此美好和伟大 但没有一个论点足够令人信服 我想知道是否有人能真正告诉我通过序列化一个类我们真正可以实现什么 让我们先定义序列化 然后我们才能讨论它为什么如此有用 序列化只是将现有对象转换为字节数组 该
  • com.sun.xml.ws.message.saaj.SAAJHeader 无法转换为 com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader

    我正在尝试访问第三方 Web 服务 该服务要求我创建一个传递时间信息 用户名和密码的安全标头 我在网上搜索了可行的示例 并尝试了多种方法 我正在尝试使用 Java 6 中内置的内容来做到这一点 我不确定我做错了什么 从 WSDL 生成 We
  • 如何在J2ME中获取数字的幂[重复]

    这个问题在这里已经有答案了 可能的重复 J2ME power double double 数学函数实现 https stackoverflow com questions 2076913 j2me powerdouble double ma
  • Unicode(希腊语)字符存储在数据库中,例如“??????”

    数据库中的希腊字符就像问号 我找不到解决办法 我使用 Java Swing 开发了一个应用程序 但是当我在 MySQL 中插入希腊字母时 就像问号一样 我将数据库排序规则更改为 utf8 并将列也更改为 utf8 我的项目编码设置为UTF

随机推荐

  • 是否可以直接选择 EXISTS 作为位?

    我想知道是否可以做这样的事情 这不起作用 select cast exists select from theTable where theColumn like theValue as bit 看起来应该是可行的 但是很多应该在 SQL
  • MSDeploy/WebDeploy - 通过 DacPac 部署复合数据库项目

    我们有一个数据库项目 其中的视图连接到另一个数据库中的表 另一个数据库采用不同的解决方案 在我们从其他数据库添加对 DacPac 的引用之前 此构建失败 我相信这些视图被视为 复合数据库对象 因为它们引用的对象未作为脚本包含在数据库中 而是
  • 用 C/C++ 计算 32 位 CRC 查找表

    我想计算一个 32 位 CRC 查找表 我尝试的一种方法是使用以下代码这个网站 http www barrgroup com Embedded Systems How To CRC Calculation C Code include
  • Map/Set 维护唯一的数组数组,Javascript

    我正在尝试构建唯一的数组数组 这样每当我要添加新数组时 只有在集合中尚不存在该数组时才应添加它 例如 存储 1 1 2 的所有唯一排列 实际的 1 1 2 1 2 1 1 1 2 1 2 1 2 1 1 2 1 1 预期的 1 1 2 1
  • FullCalendar.js - “获取事件时出错”

    我正在使用 FullCalendar js 显示来自多个来源的 Google 日历事件 到今天为止一直工作正常 由于某种原因 FullCalendar 开始弹出 获取事件时出错 错误消息 并且所有事件显然都消失了 这是一个jsfiddle
  • 保存到 UserDefaults 时应用程序总是崩溃

    我不知道出了什么问题 extension UserDefaults static let shared UserDefaults suiteName SharedGroupName static func set object Any fo
  • 正则表达式查找具有不同顺序的相同数字的数字

    我已经在 Google 上寻找正则表达式一个小时左右了 但似乎无法解决这个问题 如果我有电话号码 请说 2345 我想找到具有相同数字但顺序不同的任何其他数字 如下所示 2345 比如我匹配 3245 or 5432 数字相同但顺序不同 我
  • 同步数据从主存储器读取/写入

    当synchronized方法执行完成时 是只将其修改的数据推送到主存 还是所有的成员变量 同样 当synchronized方法执行时 是只从主存中读取自己需要的数据 还是清除所有的成员变量 缓存中的成员变量并从主存中读取它们的值 例如 p
  • 如何在 Tensorflow 2.0 中应用 Guided BackProp?

    我从Tensorflow 2 0并尝试实现 Guided BackProp 来显示显着性图 我首先计算之间的损失y pred and y true图像的梯度 然后找到由于这种损失而导致的所有层的梯度 with tf GradientTape
  • 在React中获取存储在Azure Blob存储中的json文件数据

    我是 React 新手 我正在尝试从存储在 Azure blob 存储中的 json 文件获取数据 file https mcbstorageprod blob core windows net exports person json 我使
  • ALSA:不支持非交错访问?

    ALSA s snd pcm hw params set access http www alsa project org alsa doc alsa lib group p c m h w params html ga4c8f1c6329
  • C# 如何将整数视为数组? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 假设我有 5 个整数这不是数组 我想
  • Arduino F()宏的实现

    我试图了解 Arduino 中的 F 宏实际上对 PGMEM 和 RAM 做了什么以及运行时的影响是什么 有人可以指出定义这个宏的文件吗 这可能是旧版本 但定义它的一个地方是Wstring h as in here http andybro
  • 即使 ssh 有效,Gitlab 也无法克隆存储库

    正如标题所述 即使 ssh 似乎可以工作 我也无法从 Gitlab 6 服务器克隆存储库 当尝试克隆时 它看起来像这样 git clone ssh email protected cdn cgi l email protection 133
  • 如何正确删除使用sonata-media-bundle上传的所有图像

    我已经按照建议使用 sonata media bundle 上传了一些图像here http sonata project org bundles media 2 2 doc reference usage html media new M
  • 切换按钮和开关的区别

    切换按钮和开关有什么区别 由于它们提供相同的功能 使用切换按钮或开关的具体用例是什么 切换按钮 Switch 这更多的是一个用户体验问题 而不仅仅是编码问题 这是我的回答 该控件的描述是这样说的 Toggle是一个按钮 sap m Togg
  • 为什么 go.mod 中的所有依赖都是间接的?

    我通过运行以下命令来初始化一个 go 项目 go mod init firstgo app 我确认模块已创建 cat go mod module firstgo app go 1 18 然后我通过执行安装了对 github com gin
  • 如何使用curses在终端中编写三行不断更新的行?

    我有一个程序需要输出三个不断变化的消息 连接数 已用时间和拒绝的连接 我尝试用以下方式写它们 r 在字符串末尾并在其他开始自己的输出循环之前打印换行符 认为回车符会返回一行 但它们最终都在第一行互相覆盖 我见过类似的问题 人们推荐使用cur
  • twitter bootstrap 调整手机屏幕上的文本大小

    我是 Twitter 引导程序的新手 我隐藏了一些 tr 在手机屏幕上的帮助下class hidden phone 但我想调整显示文本的大小以适合屏幕 如何在手机屏幕上调整文本大小 如下所示 span test test test test
  • Collections.unmodifierXXX 方法是否违反 LSP? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 里氏替换原则 http en wikipedia org wiki Liskov substitution principle是原则之一SOLI