基于价值链的流程框架分类

在Java 8中,某些类在Javadoc中有一个小注释,说明它们是基于值的类 。 其中包括简短说明的链接,以及有关不使用它们的限制。 这很容易被忽略,如果这样做,则可能会在将来的Java版本中以微妙的方式破坏代码。 为了避免这种情况,我想在自己的文章中介绍基于价值的类,尽管我已经在其他文章中提到了最重要的部分。

总览

在详细说明这些限制之前,本文将首先探讨为什么存在基于值的类以及为什么限制了它们的使用(如果您不耐烦,请跳至此处 )。 它将以关于FindBugs的注释结束,不久便可以为您提供帮助。

背景

让我们快速了解为什么引入了基于值的类以及JDK中存在的类。

他们为什么存在?

Java的未来版本很可能包含值类型。 我将在未来几周内写他们( 所以 留 调整 ),并会在一些细节呈现出来。 尽管它们肯定有好处,但本博文未涉及这些好处,这可能会使限制显得毫无意义。 相信我,他们不是! 或者不要相信我自己去看 。

现在,让我们看看我已经写了些关于值类型的文章:

该想法的最大简化是,用户可以定义一种不同于类和接口的新型类型。 它们的主要特征是它们将不会通过引用(如类)来处理,而是通过值(如基元)来处理。 或者,正如Brian Goetz在他的介绍性文章《价值观的状态》中所说的那样:

像类一样的代码,像int一样工作!

重要的是要添加值类型将是不变的-就像今天的原始类型一样。

在Java 8中,值类型之前是基于值的类 。 未来它们的精确关系尚不清楚,但可能与装箱和拆箱原语(例如Integerint )相似。

当设计Optional时,现有类型与将来值类型之间的关系变得显而易见。 在指定和记录基于值的类的局限性时也是如此。

存在哪些基于价值的类?

这些都是我在JDK中找到的所有标记为基于值的类:

  • java.util: 可选 , OptionalDouble , OptionalLong , OptionalInt
  • java.time: 持续时间 , 即时 , LOCALDATE的 , LocalDateTime , 本地时间 , MONTHDAY , OffsetDateTime , OffsetTime , 期间 , 年 , YearMonth , ZonedDateTime , 了zoneid , ZoneOffset
  • java.time.chrono: HijrahDate , JapaneseDate , MinguaDate , ThaiBuddhistDate

我无法保证此列表是完整的,因为我没有找到列出所有列表的官方消息。

发布时间由杰里米·舒尔茨在CC-BY 2.0 。

此外,还有一些非JDK类应该被认为是基于值的,但不要这样说。 一个例子是Guava的Optional 。 可以肯定的是,大多数代码库都将包含旨在基于值的类。

有趣的是,现有的拳击类(如IntegerDouble等)未标记为基于值。 这样做似乎是合乎需要的-毕竟它们都是此类的原型-但这样做会破坏向后兼容性,因为它将使与新限制相抵触的所有用途追溯无效。

Optional是新的,并且免责声明在第1天到来。另一方面, Integer可能受到了无可救药的污染,而且我敢肯定,如果Integer不再是可锁定的,它将破坏重要的代码(尽管我们可能会这样认为)练习。)

Brian Goetz – 2015年1月6日(格式化我的)

不过,它们非常相似,因此我们称它们为“价值至上”。

特点

在这一点上,还不清楚如何实现值类型,它们的确切属性是什么以及它们如何与基于值的类交互。 因此,对后者施加的限制不是基于现有要求,而是源自某些所需的值类型特征。 这些限制是否足以在将来与价值类型建立关系还不清楚。

话虽如此,让我们继续上面的引用:

在Java 8中,值类型之前是基于值的类 。 未来它们的精确关系尚不清楚,但可能与装箱和拆箱原语(例如Integerint )相似。 此外,编译器可能会自由地在两者之间进行静默切换以提高性能。 恰恰是,来回切换(即删除并稍后重新创建引用)也禁止将基于身份的机制应用于基于值的类。

像这样实现的JVM无需跟踪基于值的实例的身份,这可以带来实质性的性能改进和其他好处。

身分识别

在这种情况下, 身份一词很重要,因此让我们仔细看看。 考虑一个可变对象,该对象会不断更改其状态(例如正在修改的列表)。 即使对象总是“看起来”不同,我们仍然会说它是同一对象。 因此,我们区分对象的状态和身份。 在Java中,状态相等由equals (如果适当实现)和身份相等通过比较引用来确定。 换句话说,对象的标识由其引用定义。

现在假设JVM将如上所述处理值类型和基于值的类。 在那种情况下,两者都不会具有有意义的身份。 值类型将没有一个开始,就像int一样。 相应的基于值的类仅仅是值类型的盒子,JVM可以随意销毁和随意创建它们。 因此,尽管当然有对单个盒子的引用,但不能完全保证它们将如何存在。

这意味着,即使程序员可以查看代码并遵循在各处传递的基于值的类的实例,JVM的行为也可能有所不同。 它可能会删除引用(从而破坏对象的标识)并将其作为值类型传递。 如果是身份敏感操作,则可能会重新创建一个新引用。

关于身份,最好考虑基于值的类,例如整数:谈论“ 3”( int )的不同实例毫无意义,谈论“ 11:42 pm”的不同实例也没有意义( LocalTime )。

如果基于值的类的实例没有标识,则只能通过比较它们的状态(通过实现equals来确定)来确定其equals 。 这具有重要的含义,即状态相同的两个实例必须完全可互换,这意味着用另一个实例替换一个这样的实例必须不会产生任何明显的影响。

这间接确定了应将哪些内容视为基于值的实例状态的一部分。 所有类型为基本类型或其他基于值的类的字段都可以成为其一部分,因为它们也可以完全互换(所有“ 3”和“ 11:42 pm”的行为都相同)。 普通班比较棘手。 由于操作可能取决于它们的身份,因此如果基于vale的实例都引用相同但不相同的实例,则通常无法将它们交换。

例如,考虑锁定String ,然后将其包装在Optional 。 在其他地方,将使用相同的字符序列创建另一个String并将其包装。 然后,这两个Optionals不可互换,因为即使它们包装相同的字符序列,这些String实例也不相同,并且一个充当锁,而另一个则不起作用。

严格解释这意味着,基于值的类必须只考虑引用本身,而不是将引用字段的状态包括在其自身的状态中。 在上面的示例中,仅当Optionals实际指向同一字符串时,才应将其视为相等。

但是,这可能过于严格,因为必须对给定的以及其他有问题的示例进行某种程度的解释。 强制基于值的类忽略诸如StringInteger类的“值-ish”类的状态非常违反直觉。

值类型框

被计划为值类型的框会增加一些其他要求。 如果不深入探讨值类型,这些将很难解释,因此我现在不再这样做。

局限性

首先,需要注意的是,在Java 8中,所有限制都是纯人工的。 JVM并不了解这类类的第一件事,现在您可以忽略所有规则而不会出错。 但这在引入值类型时可能会发生巨大变化。

正如我们在上面看到的,基于值的类的实例没有保证的身份,在定义相等性方面的宽松程度较低,并且应符合值类型框的预期要求。 这有两个含义:

  • 该类必须相应地构建。
  • 该类的实例不得用于基于身份的操作。

这是Javadoc中所述限制的基础,因此可以将其分为对类的声明和其实例的使用的限制。

申报地点

直接来自文档(编号和格式编号):

基于值的类的实例:

  1. 是最终的且不可变的(尽管可能包含对可变对象的引用);
  2. 具有equalshashCodetoString ,它们仅根据实例的状态而不是根据其标识或任何其他对象或变量的状态来计算;
  3. 不使用身份敏感的操作,例如实例之间的引用相等( == ),实例的身份哈希码或实例的固有锁上的同步;
  4. 仅基于equals()而不是基于引用相等( == )被视为相等;
  5. 没有可访问的构造函数,而是通过工厂方法实例化的,该方法对提交的实例的身份没有任何承诺;
  6. 在相等时可以自由替换,这意味着在任何计算或方法调用中互换equals()任意两个实例xy都不会在行为上产生任何可见的变化。

通过上面讨论的内容,大多数这些规则都是显而易见的。

规则1的动机是基于价值的类,是价值类型的盒子。 出于技术和设计原因,这些必须是最终的且不可更改,并将这些要求转移到其包装盒中。

规则2 模糊地解决了有关如何定义基于值的类的状态的问题。 规则的精确效果取决于对“实例状态”和“任何其他变量”的解释。 读取它的一种方法是在状态中包括“值-ish”类,并将典型的引用类型视为其他变量。

3号到6号表示缺少的身份。

有趣的是, Optional打破了规则2,因为它在包装后的值上调用了equals 。 同样, java.timejava.time.chrono所有基于值的类都通过可序列化(这是基于身份的操作,请参见下文) java.time.chrono破坏规则3。

使用网站

再次从文档中:

如果程序尝试直接通过引用相等性或通过呼吁同步,身份哈希,序列化或任何其他身份敏感机制间接地将两个引用区分为基于值的类的相等值,则可能会产生不可预测的结果。

考虑到缺少的身份,直接区分参考是不言而喻的。 但是,没有解释为什么列出的示例违反了该规则,所以让我们仔细看看。 我列出了所有可以解决的违规事项,并提供了简短的解释和具体案例( vbi代表基于值的类的实例 ):

参考比较:这显然根据实例的身份来区分实例。

vbi的序列化:希望使值类型可序列化,并且有意义的定义似乎很简单。 但是,今天,序列化对对象身份做出了承诺,这与基于身份的无价值类的概念相冲突。 在其当前实现中,序列化在遍历对象图时还使用对象标识。 因此,目前,必须将其视为基于身份的操作,应避免使用。

情况:

  • 可序列化类中的非临时字段
  • 通过ObjectOutputStream.writeObject直接序列化

锁定vbi:使用对象标头访问实例的监视器–基于值的类的标头可以自由删除和重新创建,并且基本/值类型没有标头。

情况:

  • 在同步块中使用
  • 调用Object.wait,Object.notify或Object.notifyAll

身份哈希码:要求该哈希码在实例的生存期内保持不变。 由于基于价值的类的实例可以自由删除并重新创建,因此从某种意义上说,对于开发人员而言,恒定性是无法保证的。

情况:

  • System.identityHashCode的参数
  • 键入IdentityHashMap

突出显示其他违规或对说明进行改进的评论将不胜感激!

查找错误

当然,了解所有这些是很好的,但这并不意味着可以阻止您超越规则的工具并不会真正有用。 作为FindBugs的重度用户,我决定要求项目实施此功能,并创建了功能请求 。 该票证涵盖了使用站点的限制,并将帮助您在JDK以及您自己的基于值的类(带有注释的类)中维护它们。

由于对FindBugs感到好奇,并且想要做出贡献,我决定着手尝试自己实施它。 因此,如果您要问为什么花这么长时间准备好该功能,现在您知道了:这是我的错。 但是谈话很便宜,所以为什么不加入我的行列呢? 我在GitHub上放置了一个FindBugs克隆 ,您可以看到此pull请求中的进度。

一旦完成,我计划也要实现声明站点的规则,因此可以确保在值类型最终出现时正确编写并准备好基于值的类。

反射

我们已经看到,基于值的类是值类型的先驱。 随着Java的变化,这些实例将没有有意义的身份,并且定义它们的状态的可能性也将有限,这将对其声明和使用产生限制。 这些限制已详细讨论。

翻译自: https://www.javacodegeeks.com/2015/02/value-based-classes.html

基于价值链的流程框架分类

基于价值链的流程框架分类_基于价值的类相关推荐

  1. 基于python的深度学习框架有_《用Python实现深度学习框架》上市

    朋友们,<用Python实现深度学习框架>已经由人民邮电出版社出版上市了.在这本书中,我们带领读者仅用Python+Numpy实现一个基于计算图的深度学习框架MatrixSlow.本书讲解 ...

  2. 审批流程java 代码_基于jsp的企业流程审批系统-JavaEE实现企业流程审批系统 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的企业流程审批系统, 该项目可用各类java课程设计大作业中, 企业流程审批系统的系统架构分为前后台两部分, 最终实 ...

  3. 如何使用CNN进行物体识别和分类_基于CNN目标检测方法(RCNN系列,YOLO,SSD)

    转载自:基于CNN目标检测方法(RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN,YOLO,SSD)行人检测 一.研究意义 卷积神经网络(CNN)由于其强大的特征提取能力,近年 ...

  4. 基于python的电商网站建设_基于Django的电子商务网站开发

    Python的安装 目前市场上Python 2.X系列与Python 3.X系列共存的现象.读者可以安装Python 2.X系列或者Python 3.X系列.如果开发的目的是基于原有Python 2. ...

  5. python遥感影像地物分类_基于轻量化语义分割网络的遥感图像地物分类方法与流程...

    本发明属于图像处理 技术领域: ,特别涉及一种地物分类方法,可用于土地利用分析.环境保护以及城市规划. 背景技术: :遥感图像地物分类,旨在取代繁琐的人工作业,利用地物分类方法,得到输入遥感图像的地物 ...

  6. svm对未知数据的分类_基于SVM的高维不平衡数据分类方法与流程

    https://blog.csdn.net/weixin_39833270/article/details/111519043

  7. pytorch 三维点分类_基于深度学习的三维重建——MVSNet系列论文解读

    欢迎关注微信公众号"3D视觉学习笔记",分享博士期间3D视觉学习收获 MVSNet:香港科技大学的权龙教授团队的MVSNet(2018年ECCV)开启了用深度做多视图三维重建的先河 ...

  8. 基于cnn的短文本分类_基于时频分布和CNN的信号调制识别分类方法

    文章来源:IET Radar, Sonar & Navigation, 2018, Vol. 12, Iss. 2, pp. 244-249. 作者:Juan Zhang1, Yong Li2 ...

  9. 若依的框架怎么样_基于bootstrapTable的若依框架如何获取表格选中行的整行数据?...

    导语 项目是基于若依框架写的,大部分的底层技术都是bootstrap. 最近在写一个项目的时候遇见一个需求,需要将子页面表格中选中的数据回传给父页面.为了减少网络请求,所以就准备直接使用子父页面传值. ...

最新文章

  1. 未来哲学的六个问题域
  2. (二)Thymeleaf标准表达式之——简单表达式
  3. 每天进步一点之C\C++
  4. Qt5布局管理(2)
  5. ASP.NET状态管理
  6. java中怎么进行字符串替换?
  7. 互联网、SaaS的技术挑战与机遇
  8. linux接收网络数据并存存储,Linux网络设备驱动之数据接收流程(六)
  9. PHP正则表达式实例汇总
  10. 14寸笔记本电脑_华为笔记本电脑该如何选择?横向对比华为三款14寸笔记本
  11. Atitit.跨语言标准化 web cgi api v2 saa CGI   (通用网关接口)  编辑 CGI 是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CG
  12. WareZ盗版组织揭密-服气了-纯技术牛人
  13. nmap 扫描服务器开放了哪些端口
  14. C语言1.打印各种三角形
  15. 计算机网络应用班级口号霸气押韵,跑操口号大全(精选50句)
  16. 北航计算机博士后,北京航空航天大学博士后待遇
  17. 百练1724ROADS
  18. 2021建筑起重司索信号工模拟考试单选题库及答案解析
  19. 00_00 python机器学习_各章实例代码汇总(随学习进度更新)
  20. Timingdesigner timing designer 入门 基础 教程

热门文章

  1. 【2018.4.14】模拟赛之三-ssl2393 单元格
  2. codeforce23 E. Tree(高精度+树形dp)
  3. Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final)
  4. 各种模板(数据结构图论)
  5. 【线段树】扇形面积并(P3997)
  6. 【斜率优化】仓库建设(luogu 2120)
  7. [USACO]Sprinklers 2: Return of the Alfalfa P(网格DP)
  8. 禁用Cookie后,Session怎么样使用
  9. 两个月拿到N个offer,看看我是如何做到的
  10. jQuery 基础教程 (三)之jQuery的选择器