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 / Class 和 Primitive 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