技术拾遗
Created|Updated|Java
|Word Count:189|Reading Time:1mins|Post Views:
Java
Java 8
Lambda
Java 8 Lambdas - A Peek Under the Hood
What does $$ in javac generated name mean?
-
lambda 表达式并不总是持有外部 enclosing object 的引用,如果它不访问任何外部变量,即不持有这样的引用。只要设计一个对比实验,就会发现引用过外部变量的lambda实例才会产生一个 arg 的隐式参数引用。而内部类内部总是含有一个
this$0。 -
lambda表达式是词法作用域的-意思是不产生新的作用域,不产生任何shadowing问题。它可以无缝访问外部作用域的东西,就好像从一个 if block 里访问一个方法里的其他变量一样。但,同样地,不能声明新变量。
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2026-10-04
深入 Play E01:Scala API 对照,Action、Future 与类型化请求
Java 方法返回 CompletionStage<play.mvc.Result>,Scala 方法返回 Action[A],其中异步处理函数产生 Future[play.api.mvc.Result]。两者能够提供相同的 HTTP 契约,但类型和组合方式并不相同。把一种 API 的 Result 直接赋给另一种,在本章的负例中会编译失败。 类型化请求还解决了另一个具体问题:身份信息如何经过 Action 组合进入异步计算。实验中的 Java 和 Scala 实现都切换到名为 api-worker 的线程,普通 ThreadLocal 没有随之传播,显式捕获的用户却保持正确。这个结果来自两个独立版本工程的真实生产 HTTP 请求。 固定两个组合,先比较 HTTP 契约 主对照固定 Play 3.0.6、Scala 2.13.15、sbt 1.10.7、JDK 21.0.11。另一个独立工程固定 Play 3.0.6 与 Scala 3.3.4,运行相同 Java、Scala 源码和同一套网络矩阵。Scala 3 构件实际包含 play_3-3.0.6、play-j...
2026-10-04
Java常用类库-13-惰性集合视图与Ordering求值边界
一次转换与一份转换规则 商品目录保存整数价格,导出前需要换算成另一单位。若将源 Map 交给 Maps.transformValues,得到的 Map 看起来已经保存换算后的价格;但转换函数没有在构造时执行。返回对象保存的是源 Map 与转换规则,读取某个值时才进行计算。 这种设计可以让结果随目录修改持续变化,也使同一次导出中的重复查询可能重复计算。若转换函数执行远程查询、记录日志或读取当前汇率,重复读取不只增加工作量,还可能得到不同结果。选择集合工具之前,必须确定需要“实时读取源状态”的视图,还是“在某个时间点完成计算”的结果集合。 实验固定 Guava 33.5.0-jre,源码 SHA 为 8868c096cfdabbe38170b6e395369c315cfb72a1,使用 Java 8 语法。完整测试源码包含 Map 转换、Iterable 转换、分区和集合运算、排序四组场景,RUN.md给出 JDK 8 与 JDK 21 的复跑命令。容器与元素的共享边界见 第 02 篇。 用计数器辨认真正的计算时机 源 Map 按顺序保存 sku-a=10、sku-b=20。转换函数...

2026-10-04
企业应用架构06:Repository、Gateway与查询对象
查询“某租户在指定时段可租的相机”需要同时理解类别、设备资格、取消历史和半开租期。把它改写成几个通用 findAll 调用,很容易漏掉条件。企业应用架构05:Active Record与Data Mapper 已完成合同落库,本篇在真实数据集上区分业务集合查询、外部资源访问和查询条件表达。 三个名字对应不同职责 Fowler 的 Repository 在领域与数据映射之间提供接近集合的访问方式,调用者按领域需要寻找对象。Gateway 封装外部资源的访问接口,让其调用方式适合本地代码。Query Object 则用对象结构表达查询,并把结构解释成数据库查询。它们可以协作,不能靠统一加一个 Repository 后缀消除区别。 本例 EquipmentRepository 提供 available,返回满足规则的设备身份集合。AvailabilityQuery 固定表达租户、类别、租期和排序,再生成参数化 SQL。InventoryGateway 读取另一份实际 H2 数据库中的仓库库存。前两者处理租赁数据,后者封装独立资源的连接和查询方式。 flowchart LR U[租...
2026-10-04
深入 Play 08:BodyParser 的类型、字节限制与请求体消费
同样是 32 字节上限,已知 Content-Length 为 35 的 JSON 请求在本批得到 413,parser 字节计数为零;没有 Content-Length 的分块请求也得到 413,却已经向计数流交付了 35 字节。长度声明可以让拒绝提前,实际字节限制仍需要流级检查。 parser 成功也不代表业务输入有效。显式 JSON parser 接收空请求体后,本版得到 null 并进入控制器;默认 parser 的空请求则返回 empty 表示。接口需要自己决定空输入能否接受,不能把两种入口的结果合并为“JSON 已经验证”。 BodyParser 返回消费器而非立即返回对象 Java BodyParser 的核心接口是: 12Accumulator<ByteString, F.Either<Result, A>> apply(Http.RequestHeader request); 它接收请求头,返回一个可以消费 ByteString 的 Accumulator。正文可能还在到达,不能把 apply 返回解释成已经取得整个输入对象。 E...
2026-10-04
Java常用类库-25-流所有权与有界读写
导入文件不能只检查读到了字符串 商品导入接收一个输入流,期望得到 UTF-8 文本。成功读取一个小文件,并不能证明导入器已经正确处理资源与输入边界:网络流可能每次只返回一个字节,文件可能带字节顺序标记,读取可能在中途失败,用户也可能提交超过内存预算的内容。方法名称中的 copy、toString、readFile,并没有统一规定谁负责关闭、允许读多少或失败后保留什么。 实验固定 Commons IO 2.22.0,源码提交为 c14acc16f73e44a75b2062b17aacb26c4feda746。Java 8 与 Java 21 分别运行完整的 Chapter25Test.java,有界复制实现见 BoundedIo.java。项目和命令见 复跑说明。本篇只使用受控字节数组与临时文件,不把本机文件测试当成网络超时验证。 短读是一次进展,不是文件结束 InputStream.read(buffer) 返回正数,只表示这次读到了这些字节;返回值小于缓冲区长度并不表示 EOF。结束信号是 -1。测试中的 ShortInput 每次最多提供一个字节,内容为 UTF-8 的“商品...

2026-10-04
设计模式 22:两条变化维度如何分开
通知原本有收据与告警两类,能发邮件和短信。旧实现分别列出四种 kind:channel 组合。现在加一个推送渠道,仅沿着旧思路复制分支,就得在两类通知各加一次,下一次增加通知类型又要给全部渠道各加一支。变化来源分别是“发送什么”和“怎样送出”。 组合两侧,不替另一侧做决定 Before.send("alert", "push", "A") 直接拒绝;旧四种组合的文本却是明确合同。After 让 Receipt、Alert 各自生成内容,通过构造参数持有 Channel 实现;新 push 通道只提供一个 message -> "push|" + message,无需再造 ReceiptPush 与 AlertPush 两个子类。 123Channel push = message -> "push|" + message;String receipt = new Receipt(push).send("A");String alert = new A...
Contents
