DDD值对象的Java实现来啦!Java 11新的值类型ValueType -jaxenter

19-11-07 banq
                   

值类型与普通类型对象的不同之处在于:值类型没有对象标头或标识,没有对值类型的引用,值类型是不可变的,并且值类型之间没有继承,因此,它没有多态性。是不是非常类似DDD的值对象?

没有标识

类似原始变量类型byte,char,short,int,long,float,double或者Boolean,没有任何标识,不像普通对象都有标识,需要使用equals()方法去比较它们。

没有引用

值存储在变量中,而不存储在堆heap中。当将值类型作为参数传递给方法时,该方法将接收原始值类型的“副本”,这是因为Java通过值而不是通过引用传递所有参数。随着值类型的引入,这不会改变。将值类型作为参数传递给方法调用时,该值类型的所有位都将复制到该方法的本地参数变量中。

没有对象头部

由于值类型是值,存储在变量中而不是堆中,因此它们不需要标头。编译器仅知道变量的类型,程序应以何种方式处理该变量中的bit位即可。类似原始类型一样,当我们创建一个值类型的数组时,这些值将一个接一个地包装在内存中。这意味着对于值类型,我们将不会遇到对象数组所具有的问题。没有对数组中各个元素的引用,它们不能分散在内存中。当CPU加载第一个元素时,它将加载同一内存页面上的所有元素,并且访问连续元素将利用处理器缓存的优势。

没有继承

值类型之间可能存在继承,但是编译器将很难管理它,并且不会带来很多好处。我敢说允许继承不仅会给编译器造成问题,还会诱使没有经验的程序员创建弊大于利的构造。在即将发布的支持值类型的Java版本中,值类型之间或类与值类型之间将没有继承。这是一个设计决策。

没有多态

由于没有继承,因此不能有值类型多态性。但是,还有更多的原因表明对值类型实现多态是不合理的。

不变性

不变性是设计决定,但这是自然的方式。Java中的值类型是不可变的。不变性通常是一件好事。不可变对象有很大的帮助,在清洁和线程安全的方式编码。不变性并不能解决所有的问题,但很多时候更是得心应手。

如果您考虑int作为一个数字,很明显您不能更改其值。如果变量保留整数值2,则可以更改存储在变量中的值,但不能将值本身更改为3。

您可以更改保存值类型的变量的内容,但不能更改值类型本身。当您更改某个位时,实际上,根据哲学,您创建了一个新的值类型并存储了新值来代替旧值。

不变性是一种特性,它与不能引用值类型这一事实密切相关。从理论上讲,Java可以允许我们修改值类型的字段。结果本质上是相同的:我们获得了不同的值。这样,在值类型的情况下不变性不受限制。这仅取决于我们如何编写程序以及如何考虑值类型。将它们视为诸如数字之类的价值,本质上是不变的,被认为是一种健康的思维方式。

玩耍

在JEP 169下的Valhalla项目中,正在为Java开发值类型。目前,有一个早期访问版本可以尝试。此版本是Java 11版本的Java分支,并且有一些限制。您可以下载早期访问版本。JEP主页是https://openjdk.java.net/jeps/169,您可以从https://jdk.java.net/valhalla/下载EA版本。

您可以尝试使用Eclipse,IntelliJ或记事本来编辑源代码,但至少在IntelliJ 2019.EA版中,我无法构建代码。即使该代码是Java 11的源代码,IntelliJ仍将其识别为Java 13,这顺便说一句,暗示了我们可以期望发行版本中的值类型。可以手动执行命令行javac命令,然后手动java启动JVM命令来完成代码的编译。即使我对Maven的了解比对ANT的熟悉,我仍可以设法与IntelliJ提取的ANT脚本相处。

总结

Java发展迅速。在过去的两年中出现了许多新事物,并且正在酝酿中的许多新事物将在未来提供。值类型功能是其中之一。本文介绍了此功能的主要特征,并简要介绍了这项新技术。Java还是一种主要的编程语言,也许它是在专业环境中仅次于COBOL的第二广泛使用的编程语言。

更详细情况点击标题见原文。

                   

4