深入剖析 Java 新特性
范学雷
前 Oracle 首席软件工程师,Java SE 安全组成员,OpenJDK 评审成员
16539 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 23 讲
深入剖析 Java 新特性
15
15
1.0x
00:00/00:00
登录|注册

03 | 档案类:怎么精简地表达不可变数据?

你好,我是范学雷。今天,我们聊一聊 Java 的档案类。
档案类这个特性,首先在 JDK 14 中以预览版的形式发布。在 JDK 15 中,改进的档案类再次以预览版的形式发布。最后,档案类在 JDK 16正式发布
那么,什么是档案类呢?档案类的英文,使用的词汇是“record”。官方的说法,Java 档案类是用来表示不可变数据的透明载体。这样的表述,有两个关键词,一个是不可变的数据,另一个是透明的载体。
该怎么理解“不可变的数据”和“透明的载体”呢?我们还是通过案例和代码,一步一步地来拆解、理解这些概念。

阅读案例

在面向对象的编程语言中,研究表示形状的类是一个常用的教学案例。今天的评审案例,我们从形状的子类圆形开始,来看一看面向对象编程实践中,这个类的设计和演化。
下面的这段代码,就是一个简单的、典型的圆形类的定义。这个抽象类的名字是 Circle。它有一个私有的变量 radius,用来表示圆的半径。有一个构造方法,用来生成圆形的实例。有一个设置半径的方法 setRadius,一个读取半径的方法 getRadius。还有一个重写的方法 getArea,用来计算圆形的面积。
package co.ivi.jus.record.former;
public final class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了Java档案类的特性及其在面向对象编程中的应用。通过案例和代码详细介绍了面向对象编程中的圆形类设计和演化,以及多线程安全问题的解决。文章指出了传统设计的缺陷,并阐述了引入不可变对象的优势,包括天生的多线程安全和简化的代码。进一步介绍了不可变的正方形类设计,并提出了使用档案类来进一步简化相似的代码。通过对比传统类和档案类的代码,展示了档案类在简化代码、提高生产力方面的优势。此外,档案类内置了缺省的equals方法、hashCode方法以及toString方法的实现,减少了代码数量,提高了编码的效率,同时避免了编码错误,提高了产品的质量。总体而言,本文为读者呈现了Java档案类的特性和优势,为他们提供了深入了解和应用该技术的指导。文章还提到了使用档案类的几个容易忽略的陷阱,并给出了技术要点和思考题,帮助读者更好地理解和应用Java档案类。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入剖析 Java 新特性》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(21)

  • 最新
  • 精选
  • Jxin
    1.这不是kt吗。看来java也在吸收派生语言的基因啊,不论优秀与否。 2.这玩意,很遗憾,节省不了太多代码工作。虽然我处理不了这个bug,但我写了自动检测和修复数据的外挂,无需为bug产生的问题花费时间。jdk8我们虽然没有语言层面的支持,但我们有idea和第三方工具包呀。我没办法用 record, 但我可以一键生成我要的不可变类,包括需要的缺省实现。(代码会比较冗余?其实也还好,因为像缺省实现这种都是可以做编译期代码增强的,在类上其实就是挂个注解) 3.能处理bug总是比挂个自动修复来得要好。所以语言既然支持了,当然是好事。就是不知道我还能肆无忌惮的往属性上挂注解不,毕竟我的校验可是跟对象走的。后面可以试试。 4.核心内容可能3分钟就讲完,但这篇讲了22分钟。不确定对新手同学的体验是否会比较好,可能调研下用户体验再看是否要调整行文风格会好些。毕竟专栏的关键是听众听的逻辑,而不是作者写的逻辑。精细是好事,但要当心越描越黑。脱裤子就一句话,大家能懂。但如果拆解成,双手举到腰间,握紧皮带,推至膝盖,重心微微右移,缓缓弯曲左脚。关联上反而费劲了。 课后题 1.社会保障🐎如果直接用数组表示就属于基础类型偏执,是坏味道,所以这里封装了一个类。但活学活用好像也没用,record 的声明不能直接解决问题,毕竟数组上的元素变动不改变数组对象本身的引用。还是得自己加代码,看是禁止写操作还是写时复制。 2.不能直接继承也是个问题,如果要想实现自动扩容,不能直接继承list的实现子类。得自个重写。

    作者回复: 谢谢大侠订阅我写的小专栏,还码了这么多字,不胜惶恐。 1. 不是。 2. 长见识了。 3. 又长见识了。 4. 多谢言传身教。

    2021-11-21
    4
    9
  • LeaveStyle
    在没有record之前,我们在工作中一般使用lombok来帮助我们定义model,在lombok的config文件中禁用掉了setter相关,让model为只读状态。如果想修改model中的字段值,我们一般两种方式: 1. @With 修改单值 -> 返回一个新对象 2. @Builder(toBuilder = true) 修改多个值 -> 返回一个新对象 现在有了record能进一步简化一些代码,继续使用@With和@Builder来修改数据值。

    作者回复: 今天我学到新东西了,谢谢!

    2021-11-23
    2
    6
  • ABC
    java.time整个包都被设计成了不可变类,而且代码编码方式和本文中的不可变类设计如出一辙,想请问老师,预测一下,OpenJDK后面会有计划用封闭类重构java.time包吗?

    作者回复: 是这样的,但是重构的话,短期看可能性不太大,主要是太忙了。估计要到JDK 21或者25的时候,Java语言会重上一个新台阶。以后,可能才会考虑重构很多标准类库。

    2021-11-19
    3
  • 多属性的时候怎么用呢?比如有十几个甚至几十个属性,定义时写在名称后的小括号里会很长,不直观,初始化的时候通过构造方法的参数赋值,也会很长不直观

    作者回复: 如果属性很多,可能就要考虑是不是需要拆分了。

    2021-11-19
    2
    3
  • ABC
    在想一个问题: Java 8在写java.time包的时候,要是知道会增加封闭类这个特性.会不会简化不少代码?

    作者回复: 我想这是确定的。不仅仅是java.time,很多包的设计都会不同,代码也会减少很多。

    2021-11-19
    2
    2
  • 雷霹雳的爸爸
    对数组和集合field得保护性复制,或者对集合做不可修改得处理,是不是还得考虑复写读取方法

    作者回复: 是的,这是两个容易出问题的数据结构。

    2021-11-19
    2
  • 拉欧
    这不就是scala里面的case class吗,看来scala就是给java探路用的吧

    作者回复: 哈哈,scala里有很多好玩的简化。

    2022-05-17
    1
  • 码农Kevin亮
    如果类有多个构造方法,档案类是不是不支持呢?

    作者回复: 档案类用来简洁地表达不可变类,目前还没有看到支持多个构造方法的必要性。

    2021-11-23
    1
  • TableBear
    看来要下载个JDK17才能完成课后思考题了😂

    作者回复: 建议使用JDK 17, 并且使用预览版模式。

    2021-11-20
    2
    1
  • chris
    请问这个档案类在jvm里面是怎么实现的, 可以作为值类型吗?还是只是语法糖?

    作者回复: 都不是

    2021-12-18
收起评论
显示
设置
留言
21
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部