2022年Java将有什么新的特性和改进,我相信很多Java开发者都想知道。结合Java语言架构师布莱恩·格茨Brian Goetz)最近的一些分享,胖哥给大家爆个料。老规矩,点赞走起。

Valhalla

布莱恩·格茨在去年底发表了一篇名为State of Valhalla的文章,里面信息量非常大,里面提到早在2014年Java项目组就启动了一个名叫Valhalla的项目,这个项目将为JVM平台带来更加灵活的、扁平化的数据类型。在2021年该项目将有进一步的动作,值对象(value objects)原始类(primitive classes)专用泛型(specialized generics)即将引入JVM平台。今天先来聊聊这个值对象是个啥。

我们知道什么是“值”,什么是“对象”,但是什么是“值对象”呢?不光你们懵逼,我也懵逼,来一起研究研究。

Java类型系统的不足

Java类型系统由内置的10种类型组成,这10种类型无法直接表达复杂的数据结构,例如字符串、三维坐标、空间向量等等,但是开发者可以用这10种类型来为业务实体建模,Java的类型体系是非常有用的。

但是Java类型仍然存在“缺陷”, 同一个类的两个对象包含完全相同的属性,但是它们的内存寻址是不一样的。

所以从某种意义上说,他们有自己的身份标识。

但是对于原始类型就不一样了,如果一个int类型的变量值为7,另一个也为7,区分它们有意义吗?这个7还是那个7?显然是无意义的。

让我们再来举一个现实中的例子,两件相同尺寸、材质的红色衣服肯定是两件不同的衣服,但是它们的材质肯定是一种材质,颜色肯定是一种颜色,不会有傻子认为这是两种颜色。这里面的尺寸当然可以通过Java中的原始类型去描述,但是材质和颜色不行(虽然颜色可以用十六进制表示),这里的尺寸、材质、颜色都应该被认为是原语。

这个痛点促使了Valhalla项目的诞生。

对象头

为了理解Valhalla引入的 Value Object / ClassPrimitive Object / Class 概念能够给我们带来了什么,我们需要看看JVM是如何将对象保存在内存中的。

对象头对类的对象非常重要,决定哪个线程可以访问对象、垃圾收集器标记、对象hash;更重要的还有对象的类型指针,它能够在运行时动态访问对象的类,并从其类到该对象的详细信息,比如继承多态、反射。

但是凡事都有两面性,Java对象内存占用的大小取决于它所包含的信息的总和,对象头在 64 位系统上至少需要 16 个字节,在 32 位系统上至少需要 8 个字节(当然JVM可以通过配置项去设置如何保存对象头)。很多对象不需要多线程,也不需要什么对象标识,就像上面提到的衣服的颜色,只有颜色的值才是我们关心的事。这种冗余的内存占用让Java为人诟病。

Value Class

对于许多对象来说,它属性值的相等性是我们关心的,其它类信息没什么用,而且只为保存值和对这些值进行操作而编写的类在所有类中所占的比例非常大。Valhalla项目为这样的场景引入了一个新的类类型:Value Class。目前还只是JEP草案,但是已经初具形态:

value class Substring implements CharSequence {
private String str;
private int start;
private int end; public Substring(String str, int start, int end) {
checkBounds(start, end, str.length());
this.str = str;
this.start = start;
this.end = end;
} public int length() {
return end - start;
} public char charAt(int i) {
checkBounds(0, i, length());
return str.charAt(start + i);
} public Substring subSequence(int s, int e) {
checkBounds(s, e, length());
return new Substring(str, start + s, start + e);
} public String toString() {
return str.substring(start, end);
} private static void checkBounds(int start, int end, int length) {
if (start < 0 || end < start || length < end)
throw new IndexOutOfBoundsException();
}
}

Value Class和我们常见的类差不多,但是它可能(这里依然在讨论中)具有下面一些特性:

  • 值对象是没有身份的对象,通常情况下我们用==运算符检查身份,这里可能和equals()不再有区别。

  • 值类本身和它的所有字段默认都是final的。

  • 该类不直接或间接地实现java.lang.IdentityObject(有身份标识类的新超类)。这意味着超类要么是无状态抽象类,要么Object是无状态抽象类。

  • 值类都是java.lang.ValueObject的隐式实现。

  • 没有构造super函数调用构造函数。将在不执行任何超类初始化代码的情况下创建实例。

  • 无法在值类中使用synchronized关键字。

  • (可能)该类没有声明finalize()方法。

  • (可能)构造函数不使用this来设置构造函数主体中的字段,或者可能在所有字段都明确内存分配之后。

其它的操作和普通的类应该差别不大,但是要注意的是,JDK标准库中的一些原有类如果被认定为Value Class需要做兼容性处理。

value要成为保留字还是关键字?

这不是全部

Value Class对Java类对象头进行了阉割,有利于降低Java的内存消耗,但是这不是Valhalla计划的全部。对于这一部分过于超前的内容,我写起来其实是很有困难的,构思了好几天,从场景出发来了解一门编程语言的设计有利于从根本提高自己。如果你想了解更多关于Valhalla的东西,可以关注我,我会继续分享相关的知识。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

Java将引入新的对象类型来解决内存利用问题的更多相关文章

  1. SAP CRM 用户界面对象类型和设计对象

    在CRM中的用户界面对象类型的帮助下,我们可以做这些工作: 进行不同的视图配置 创建动态导航 从设计层控制字段标签.值帮助 控制BOL对象的属性的可视性 从导航栏访问自定义组件 一个用户界面对象类型之 ...

  2. Spring实战(十)Spring AOP应用——为方法引入新功能、为对象引入新方法

    切面最基本的元素是通知和切点,切点用于准确定位应该在什么地方应用切面的通知. 1.Spring借助AspectJ的切点表达式语言来定义Spring切面 在Spring中,要使用AspectJ的切点表达 ...

  3. JAVA IO分析二:字节数组流、基本数据&对象类型的数据流、打印流

    上一节,我们分析了常见的节点流(FileInputStream/FileOutputStream  FileReader/FileWrite)和常见的处理流(BufferedInputStream/B ...

  4. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  5. [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. 2016年11月3日JS脚本简介数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6.布尔型数据:bool 7.对象类型:object 8.二进制:binary 语言类型: 1.强类型语言:c++ c c# java 2.弱类型语

    数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6 ...

  7. python与java的内存机制不一样;java的方法会进入方法区直到对象消失 方法才会消失;python的方法是对象每次调用都会创建新的对象 内存地址都不i一样

    python与java的内存机制不一样;java的方法会进入方法区直到对象消失 方法才会消失;python的方法是对象每次调用都会创建新的对象 内存地址都不i一样

  8. objective-c和java下解析对象类型和数组类型JSON字符串

    首先讲objective-c如何实现: 这里需要用到2个插件,一个是JSONKit,另一个是Jastor,一共包含6个文件,3个.h头文件和3个.m实现文件.在ARC的工程中如何导入不支持ARC的第三 ...

  9. Java 基本类型和对象类型的区别

    Java 基本类型和对象类型的区别 基本类型: int long byte float double char boolean short 对象类型: Integer Long Byte Float ...

随机推荐

  1. Tornadofx学习笔记(4)——IconTextFx开源库,整合5000+个字体图标

    JavaFx中其实也可以直接使用字体图标iconfont的,只需要加载ttf字体文件,之后设置unicode即可,具体可以看我给出的代码 既然JavaFx可以,那么以JavaFx为基础的Tornado ...

  2. LuoguP1898 缘分计算 题解

    Content 根据一个长度为 \(l\),只含大写字母的字符串算出它的"缘分值". 步骤如下: 给定一个数 \(st\). 将字符串里面的所有字母改成数字(如 A 改成 \(st ...

  3. AcWing03. 完全背包问题

    有\(N\)种物品和一个容量是\(V\)的背包,每种物品都有无限件可用. 第\(i\)种物品的体积是\(v_i\),价值是\(w_i\). 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量, ...

  4. SpringBoot整合quartz实现动态启动,停止定时任务功能

    注意:这个方法当程序重启之后会失效,所以必须将定时任务持久化到数据库,然后程序启动的时候重新把数据库的定时任务加载到quartz中 springboot程序启动初始化代码参考:https://www. ...

  5. c++11之日期和时间库

    本文主要介绍 std::chrono日期和时间用法. 演示环境: vs2017 0.头文件 1 #include <chrono> 2 #include <thread>// ...

  6. 【LeetCode】100. Same Tree 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 [LeetCode] 题目地址:https:/ ...

  7. 【剑指Offer】从上往下打印二叉树 解题报告(Python)

    [剑指Offer]从上往下打印二叉树 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...

  8. 【LeetCode】821. Shortest Distance to a Character 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 过两遍数组 日期 题目地址:https://leet ...

  9. 【LeetCode】814. Binary Tree Pruning 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 后序遍历 日期 题目地址:https://leetc ...

  10. A. Toda 2

    A. Toda 2 time limit per test 2 seconds memory limit per test 512 megabytes input standard input out ...