拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Java将引入新的物件型别来解决存储器利用问题

Java将引入新的物件型别来解决存储器利用问题

白鹭 - 2022-03-11 1969 0 0

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

Valhalla

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

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

Java型别系统的不足

Java的型别系统

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

但是Java型别仍然存在“缺陷”, 同一个类的两个物件包含完全相同的属性,但是它们的存储器寻址是不一样的,

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

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

物件头

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

关注公众号:Felordcn 获取更多信息

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

博主:码农小胖哥
出处:felord.cn
本文著作权归原作者所有,不可商用,转载需要宣告出处,否则保留追究法律责任的权利,如果文中有什么错误,欢迎指出,以免更多的人被误导,
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *