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

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

在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

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

由Jeremy Schultz在CC-BY 2.0下发布。

发布时间由杰里米·舒尔茨在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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中数组所占字节怎么算

数组在内存中所占字节数可以使用sizeof操作符来计算,该操作符是专门用于检测类型或变量或数组在内存中所占有的空间(字节数);语法“sizeof(x)”,其中x是类型名、变量名或数组名等,可以返回x所占字节数。C语…

c 中头文件和源文件的区别是什么

区别:头文件是“.h”文件,提供接口;源文件是“.cpp”文件,提供实现。编译器规定源文件必须包含函数入口,即main函数;而头文件不得包含函数入口,头文件不可以单独编译成一个程序,仅仅…

rest api_REST API的演变

rest api每个开发人员都以某种方式接触到API 。 要么为一家大公司集成一个主要系统,或者使用最新的图形库生成一些精美的图表,要么直接与他喜欢的编程语言进行交互。 事实是,API无处不在! 它们实际上代表了当今Internet的基本构建…

在c程序中,注释语句只能位于一条语句的后面吗

C语言中的注释在编写C语言源代码时,应该多使用注释,这样有助于对代码的理解。在C语言中有两种注释方式:一种是以/*开始、以*/结束的块注释(block comment);另一种是以//开始、以换行符结束的单行注释&#…

C 运算符中不能重载的是哪些

C 运算符中不能重载的有:1、条件运算符“?:”;2、成员访问运算符“.”;3、域运算符“::”;4、长度运算符“sizeof”;5、成员指针访问运算符“->*”和“.*” 。重载:让操作符可以有新的语义,…

C语言字符串输出函数puts()的作用是什么

C语言字符串输出函数puts()的作用:puts()在显示字符串时会自动在其末尾添加一个换行符。puts()遇到空字符时就停止输出,所以必须确保有空字符。  下面两个示例分别说明puts()的两个特点。  示例1:/* put_out.c -- using puts() */#includ…

maf中anglearc_Oracle MAF中的LOV

maf中anglearc我们都喜欢最强大的ADF功能值列表之一。 使用它们,我们可以声明并轻松地在ADF应用程序中构建非常复杂的功能。 一件好事是,我们在Oracle MAF中也有类似的方法。 在ADF BC中,我们在业务服务级别(基本上在实体或VO级别…

一个c程序的执行是从哪里开始到哪里结束

一个C程序的执行是从main函数开始到main函数结束。C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语…

java9 coutdown_Java并发之CountDownLatch

正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。在Java并发中,countdownlatch的概念是一个常见的面试题,所以一定要确保你很好的理解…

jsf 写一个action_一个JSF清单示例

jsf 写一个action这是使用JSF 2.0(JavaServer Faces)构建的示例列表应用程序。 该应用程序是待办事项列表。 该应用程序具有添加,编辑或删除列表中项目的功能。 待办事项具有名称和描述属性。 完成的应用程序的JSF页面具有: 使用…

c 中=和==的区别有哪些?

c 中和的区别1、含义不同:“”是赋值的意思。它的作用是将一个表达式的值赋给一个左值。一个表达式或者是一个左值,或者是一个右值。所谓左值是指一个能用于赋值运算左边的表达式。左值必须能够被修改,不能是常量。我们用变量作左值&#xff…

java内部格式_详解java内部类的访问格式和规则

详解java内部类的访问格式和规则1.内部类的定义定义一个类来描述事物,但是这个事物其中可能还有事物,这时候在类中再定义类来描述。2.内部类访问规则①内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员&#xf…

primefaces_使用WildFly 8.2.0.Final,Primefaces 5.1和MySQL 5的JDBC领域和基于表单的身份验证...

primefaces我会不时查看我博客上最受欢迎的内容,并尝试最好地满足您的需求。 因此,阅读我的博客是其他读者推动内容的一种方式。 另一种方法是通过评论或电子邮件与我联系。 今天,我将使用Primefaces修改我的JDBC Realm示例并将其更新到最新的…

c语言语句以什么结束

c语言源程序的每一条语句都英文输入状态下的“;”结束一条语句。不同的版编权程语言有不同的结束标志,Java,C 也是以“;”作为一行语句的结束的标志,也有不需要用“;”作为一行语句结束的编程语言&#xff…

hadoop lambda_Delta架构:统一Lambda架构并利用Hadoop / REST中的Storm

hadoop lambda最近,一群人要求我详细介绍我为我们的书《分布式实时计算的风暴蓝图》撰写的Druid / Storm集成。 德鲁伊很棒。 风暴很棒。 两者一起解决了实时维查询/聚合问题。 实际上,人们正在将其视为主流,称其为RAD Stack ,并…

C语言中sizeof和strlen的区别是什么

C语言中sizeof和strlen的区别是:strlen是一个函数,用来计算指定字符串str的长度,但不包括结束字符(即null字符);而sizeof是一个单目运算符,不是函数。区别分析:strlen 是一个函数&am…

c语言中continue语句的作用是什么

continue 的作用是结束本次循环,即跳过循环体中下面尚未执行的语句,然后进行下一次是否执行循环的判定。注意:continue 语句只结束本次循环,而不是终止整个循环。continue 只能在循环语句中使用,即只能在 for、while 和…

java jar killed_容器中Java 程序OOMKilled原因浅析

背景:业务的容器化刚刚搞完,线上开始告警,容器重启,容器重启。describe pod 查看原因是OOMKilled分析:OOMKilled 是pod 中的进程使用的内存超过了.spec.containers[*].resources.limits.memory中定义的内存限制&#x…

eof在c语言中表示什么

在C语言中,或更精确地说成C标准函数库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的…

go odroid_小众奇葩!Odroid Go Super简评

小众奇葩!Odroid Go Super简评2021-02-27 17:19:277点赞11收藏18评论小编注:此篇文章来自即可瓜分10万金币,周边好礼达标就有,邀新任务奖励无上限,点击查看活动详情儿时出生于苏北小城消息闭塞 玩具不多1994年 老爸南下…